第一步:
在学习Java反射机制之前应该先去学习,类的加载机制和加载流程。只有这样才能够更加清晰的去理解和掌握Class对象的由来。Class对象是由JVM在加载完Class文件之后进行创建的,在存在于堆中,Class对象中存在着指向加载进方法区中的类信息的引用,所以通过Class对象可以清晰的窥探到整个类的结构。
第二步 理清反射的使用的思路
和类相关的信息包括,父类信息,构造函数,字段信息,方法。所以我们在进行反射的时候主要也是应该从了解类的这几种信息进行着手。为了进行操作这个类的信息,学过类加载机制的话,我自然而然的想到如何得到Class对象。
得到Class对象有三种方式,根据具体情况进行选择;
/第一种方式:
Classc1 = Class.forName("Employee");
//第二种方式:
//java中每个类型都有class 属性.
Classc2 = Employee.class;
//第三种方式:
//java语言中任何一个java对象都有getClass 方法
Employeee = new Employee();
Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
在拿到Class对象之后,我就能轻易的窥探到类的具体内部结构信息了。
onstructor getConstructor(Class[] params)根据构造函数的参数,返回一个具体的具有public属性的构造函数
Constructor getConstructors() 返回所有具有public属性的构造函数数组
Constructor getDeclaredConstructor(Class[] params) 根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
Constructor getDeclaredConstructors() 返回该类中所有的构造函数数组(不分public和非public属性)
首先我们利用反射无非就是想去使用该类的对象,实现类的实例化。可以通过有参和无参两种方式进行进行实例化
Class c =Class.forName("Employee");
//创建此Class 对象所表示的类的一个新实例
Objecto = c.newInstance(); //调用了Employee的无参数构造方法,必须有无参构造方法存在
Class clazz = InterfaceImple.class;
Constructor constructor =clazz.getConstructor(String.class,int.class);
Object obj = constructor.newInstance("ganyao",10);
接着就是操作成员变量
Field getField(String name) 根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields() 返回具有public属性的成员变量的数组
Field getDeclaredField(String name) 根据变量名,返回一个成员变量(不分public和非public属性)
Field[] getDelcaredFields() 返回所有成员变量组成的数组(不分public和非public属性)
对于字段信息的获得 可以获取所有字段的数组或者获取指定字段,也可以获取public和非public 字段
一般情况使用的是获取指定字段的值。
Field filed =clazz.getDeclaredField("str"); //获取指定的字段对象 即使字段是被private修饰的也能得到
filed.setAccessible(true); 对于Private修饰的字段可以通过设置TRUE进行操作
filed.set(obj,"hello");
logger.info((String) filed.get(obj));
最后就是操作成员方法
Method getMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的具有public属性的方法
Method[] getMethods() 返回所有具有public属性的方法数组
Method getDeclaredMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的方法(不分public和非public属性)
Method[] getDeclaredMethods() 返回该类中的所有的方法数组(不分public和非public属性)
Method method = clazz.getMethod("getStr");
logger.info((String) method.invoke(obj));