java 反射生成_Java反射机制生成实例

http://hi.baidu.com/wuming3632171/item/49834a269bf59b3794f62bc4

看了一下Java OOP的项目,在创建门禁卡登录类别时可以用工厂模式来实现;但后来又考虑了一下在应用工厂模式的同时可以应用Java的反射机制,Java反射的概念我 个人认为很不好理解,通过例子才能融会贯通;其实理解Java的反射和理解JavaScript的eval函数一样,都是将一个字符型数据转换为相应的 类、属性和方法;通过下面的例子来熟悉一下Java的反射;

首先定义一个教员类,如下:

//教员类

public class AccpTeacher {

private String name;

private int age;

public AccpTeacher() {

name = "无名氏";

age = 22;

}

public AccpTeacher(String name) {

this.name = name;

this.age = 22;

}

public String toString() {

return "名字是:" + name;

}

public String toString(int age, String name) {

this.name = name;

this.age = age;

return "名字是:" + name + ";年龄是:" + age;

}

}

如果我们实例化这个类可以用我们常用的如下方式:

public static void main(String[] args){

AccpTeacher accpTeacher = new AccpTeacher();

System.out.println(accpTeacher);

}

可以清晰的想到运行结果是:名字是:无名氏

以上是我们最常用的方式,但有时我们想通过字符串来实例化一个类如何做呢,看下面代码:

public static void main(String[] args){

// 实例化一个类

Object accpTeacher = Class.forName(AccpTeacher.class.getName()).newInstance();

System.out.println(accpTeacher);

}运行结果同样是:名字是:无名氏

首先Class.forName(类名)是将这个类加载到JVM虚拟机中,获得一个类型为Class的类,然后调用其newInstance()方法,相当于实例化(调用无参的构造函数);所以以上两段代码的运行效果是一致的。

我们看到AccpTeacher这个类有一个带参数的构造方法,那如何通过反射来调用它呢?看下面代码:

public static void main(String[] args){

// 通过构造方法实例化一个类;本例是一个有参数的构造函数,并且构造函数可以为private修饰

Class[] argtype = new Class[] { String.class };//代表构造方法的参数类型数组

Object[] argparam = new Object[] { "张三" };//代表构造方法的参数值数组

Class classType = Class.forName(AccpTeacher.class.getName());

Constructor constructor = classType.getDeclaredConstructor(argtype); //获得构造方法,argtype是参数类型数组,我们这里代表的是参数只有一个String类型

constructor.setAccessible(true);// 访问私有构造函数,Spring可以配置私有的属性和方法,其实就是用到的这里

Object accpTeacher2 = constructor.newInstance(argparam);

System.out.println(accpTeacher2);

}以上代码的运行结果是:名字是:张三

在把教员类放在这里,如下:

//教员类

public class AccpTeacher {

private String name;

private int age;

public AccpTeacher() {

name = "无名氏";

age = 22;

}

public AccpTeacher(String name) {

this.name = name;

this.age = 22;

}

public String toString() {

return "名字是:" + name;

}

public String toString(int age, String name) {

this.name = name;

this.age = age;

return "名字是:" + name + ";年龄是:" + age;

}

}下面我想修改类中的属性,看代码:

public static void main(String[] args){

// 访问类中的属性,属性可以是private修饰的

AccpTeacher accpTeacher3 = (AccpTeacher) Class.forName(

AccpTeacher.class.getName()).newInstance();//实例化一个对象

Field field = AccpTeacher.class.getDeclaredField("name");//声明一个属性对象,针对这个例子我们操作的这个属性是AccpTeacher类中的name属性

field.setAccessible(true);// 私有成员变量

System.out.println(field.get(accpTeacher3));//通过实例化的对象调用

}

以上代码的运行结果是:无名氏

再看一下修改属性:接上例

public static void main(String[] args){

// 修改类中的属性,属性可以是private修饰的

// 接上例

field.set(accpTeacher3, "李四");//属性类通过set方法设置属性的值

System.out.println(field.get(accpTeacher3));

}

以上代码的运行结果是:李四

最后我们看一下通过反射调用方法:

public static void main(String[] args){

// 调用类中的方法(无参),方法可以是private修饰的

AccpTeacher accpTeacher4 = (AccpTeacher) Class.forName(

AccpTeacher.class.getName()).newInstance();//实例化一个对象

Method

method = AccpTeacher.class.getMethod("toString",

null);//首先声明一个方法类,并通过getMethod()方法获得相应的方法,这个方法中有两个参数,第一个是方法名称的字符串,第二个是方法

中参数类型的数组,这里获得的是AccpTeacher中的toString方法

System.out.println(method.invoke(accpTeacher4, new Object[0]));//再看一下方法类中的invoke()这个方法,方法中有两个参数,第一个参数为这个方法的实例对象,第二个参数为方法参数的值的数组

}

以上代码的运行结果是:名字是:无名氏

在看带参的方法:

public static void main(String[] args){

// 调用类中的方法(有参),方法可以是private修饰的

AccpTeacher accpTeacher5 = (AccpTeacher) Class.forName(

AccpTeacher.class.getName()).newInstance();

Class[] clazz = new Class[2];//声明类型的数组,AccpTeacher中有一个toString(int,String)的方法

clazz[0] = int.class;

clazz[1] = String.class;

Method method2 = AccpTeacher.class.getMethod("toString", clazz);//获得带参数的方法

Object[] obj = new Object[2];//参数值的数组

obj[0] = 20;

obj[1] = "王五";

System.out.println(method2.invoke(accpTeacher5, obj));

}

以上代码的运行结果是:名字是:王五;年龄是:20

以下是我个人分析学习代码:

Teacher类

package test;

public class Teacher {

private String name;

private int age;

public Teacher() {

name = "无名氏";

age = 22;

}

public Teacher(String name) {

this.name = name;

this.age = 22;

}

public String toString() {

return "名字是:" + name;

}

public String toString(int age, String name) {

this.name = name;

this.age = age;

return "名字是:" + name + ";年龄是:" + age;

}

}

package test;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class Test {

public static void main(String[] args) throws Exception {

Class[] paramenterTypes=new Class[]{String.class};//参数类型

Object[] obj=new Object[]{"张三"};//参数值

Class type=Class.forName(Teacher.class.getName());//通过Class.forName()来加载类,得到这个类类型

Constructor constructor=type.getDeclaredConstructor(paramenterTypes);//由这个类类型以及它的参数得到构造器

constructor.setAccessible(true);//访问私有构造函数,Spring可以配置私有的属性和方法,其实就是用到的这里

Object o=constructor.newInstance(obj);

System.out.println(o);

Teacher t=(Teacher)Class.forName(Teacher.class.getName()).newInstance();

Field field=Teacher.class.getDeclaredField("name");

field.setAccessible(true);

System.out.println(field.get(t));

field.set(t, "李四");

System.out.println(field.get(t));

Teacher t2=(Teacher)Class.forName(Teacher.class.getName()).newInstance();

Method method=Teacher.class.getMethod("toString", null);

System.out.println(method.invoke(t2,  new Object[0]));

Teacher t3=(Teacher)Class.forName(Teacher.class.getName()).newInstance();

Class[] clazz=new Class[2];

clazz[0]=int.class;

clazz[1]=String.class;

Method method2=Teacher.class.getDeclaredMethod("toString", clazz);

Object[] objs=new Object[2];

objs[0]=20;

objs[1]="王五";

System.out.println(method2.invoke(t3, objs));

}

}

输出结果:

名字是:张三

无名氏

李四

名字是:无名氏

名字是:王五;年龄是:20

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值