java反射机制在很多框架上都有所应用,如果没有反射,那几乎大部分像Spring等得框架就不会存在,日常开发必然用的比较少,但学习了解,对以后学习框架,会有好处。
反射reflection,提供了在运行期
1、判断任一对象的所属类
2、构建任意类的对象
3、判断任意一个类的成员变量和方法,调用任意一个类的方法
4、获得,改变任意一个对象成员变量的值的功能
反射常用的类又lang包下得Class,java.lang.reflect包下的Field,Method,Array类。
java中不论一个类又多少对象,这个类所对应的Class对象只有一个,而Class对象是private,只有JVM才可以创建。
一、反射的第一步就是获取对象的Class对象:
获取Class对有3种方式:(Person类是我自己写的测试类,见末尾)
//获取Class对象的三种方式,第一种用的较多,如JDBC,会使用forName方法获得数据库驱动
Class<?> classType1 = Class.forName("com.zhumin.reflectiontest.Person");//第一种 使用Class.forname("类的全称")
System.out.println(classType1);
Class<?> classType2 = Person.class; // 第二种,使用 类名.class
System.out.println(classType2);
//第三种需要先创建一个对象
Person person = new Person();
Class<?> classType3 = person.getClass(); //比起第一种第二种,多了一步
System.out.println(classType3);
输出结果都是一样的
class com.zhumin.reflectiontest.Person
class com.zhumin.reflectiontest.Person
class com.zhumin.reflectiontest.Person
二、使用获得的classType对象创建实例,分为有参数的情况和无参数的情况
// 创建实例的两种情况
Person person1 = (Person)classType1.newInstance(); //这是构造方法无参的情况,直接调用newInstance
System.out.println(person1.getClass());
//如果有参数,就需要分为两步,1,获得构造方法,2调用newInstance(Object...)的重载方法创建实例
// 当传递的是一个空得数组的时候,就和第一种方式是一样的
Constructor constructor = classType1.getConstructor(new Class[]{int.class,String.class});
Person person2 = (Person)constructor.newInstance(22,"charleszhu");
System.out.println(person2.getClass());
打印的结果也是一样的。
三、可以根据获得的classType,可以获取类的私有和公共方法和属性,可以执行方法,也可以改变属性的值,对共有方法和属性直接调用getMethods(),和getField();对于私有的方法,则有一些变化。
//获取公共方法并且执行
Method method1 = classType1.getMethod("hello",new Class[]{int.class,String.class});
method1.invoke(person1,1,"charleszhu");
//若果需要访问private的方法和属性就需要多几个步骤
Method method2 = classType2.getDeclaredMethod("world",new Class[]{String.class});
//第二步需破解java的访问限制
method2.setAccessible(true);
method2.invoke(person1,method2.getName());
输出结果:
1charleszhu
this is a private method :world
四、补充
八个原生类型的包装类,比如 Integer.Type和Integer.class输出的结果是不一样的
System.out.println("Integer.TYPE :"+Integer.TYPE +" Integer.class: "+Integer.class);
System.out.println("int.class:" + int.class);
输出结果:
Integer.TYPE :int Integer.class: class java.lang.Integer
int.class:int
所以 Integer.TYPE==int.class
五、动态生成数组
Class<?> classType = String.class;
Object array = Array.newInstance(classType,10);// 第一个参数是数组的类型,第二个参数是数组的长度
//赋值
for (int i = 0; i <10 ; i++) {
Array.set(array,i,i+"");
}
//取值
for (int i = 0; i <10 ; i++) {
System.out.println(Array.get(array,i)); ;
}
附上Person类:
/**
* Created by charleszhu on 14-2-15.
*/
public class Person {
private int id;
private String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public Person() {
}
public void hello(int id,String name){
System.out.println(id + name);
}
private void world(String str){
System.out.println("this is a private method :" + str);
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}