上一部分介绍了反射的一些基本内容,如今将利用反射完成更多的事情。框架
1、 Field类工具
Field类封装了属性的信息,一个Field类封装了一个属性的信息,相似于Method对象封装了方法的信息同样。那么如何获取Field对象呢?在Class类中一般有如下两个方法:spa
一、Field getDeclaredField(String name) ----方法1调试
二、Field getField(String name) -----方法2对象
是否是和获取Method对象的方法很类似呢?不错,获取Field基本和获取Method对象是一致的。继承
getField 方法能够获 得本类的公开属性以及从父继承到,可是没法获非公开属性;而getDeclaredField方法只能得到本类属性,但这包括的本类的非公开属性。get
例如:要获取Student类的name属性的Field对象,可使用以下的代码:编译器
Class c=Student.class;编译
Field nameField=c.getField("name");class
这样就获取到了对应的Field对象。
那么获取到Field对象以后,咱们能够修改相关属性的值,那优点如何操做的呢?
利用public void set(Object obj,Object value)方法来修改属性
例如:
Student u =new Student();
Filed ageField=u.getClass().getDeclaredField("age");
ageField.setAccessible(true);
ageField.set(u,new Integer(18));
须要注意的是,这里咱们使用了getDeclaredField方法,由于此处的age是做为一个私有的属性的,而getField只能访问公开的属性,而对于私有的属性通常状况下是没法读取、修改的,而经过反射确能够修改,只须要增长
ageField.setAccessible(true)
代码便可。
2、利用反射调用对象的方法
利用反射调用方法,首先咱们须要获取到被调用的方法所对应的Method对象,而后利用Method对象调用invoke方法。invoke方法签名以下:
public Object invoke(Object obj,Object[] args)
在这个方法中有两个参数,参数1 obj表示对那个对象调用方法,参数2 args表示调用方法时候的参数列表,invoke方法返回值对应于Method对象所表明的方法调用时候的返回值。
例如:
Student stu=new Student();
Method m=stu.getClass().getDeclaredMethod("study",new Class[]{int.class,double.class});
Object result=m.invoke(stu,new Object[]{new Integer(10),new Double(1.5)});
上面就是利用反射调用方法。与Field对象相似,也能够调用一个类的私有方法,只须要在调用Method方法以前,先调用setAccessible(true)便可。
反射的优点:
其实总结来讲,反射的优点在于更多的复用代码,这也是为何工具和框架编写时候经常使用反射的缘由,下面一个例子大体能够窥见端倪
原:
Student s =new Student();
s.study();
反射:
String className = "Student";
Class c = Class.forName(className);
Object o = c.newInstance();
String methodName = "study";
Method m = c.getMethod(methodName , new Class[]{});
m.invoke(o , new Object[]{});
固然,这里并非鼓励你们滥用反射。反射技术有着很是显著的几个缺点。
运行效率与不用反射的代码相比会有明显降低。
2. 代码的复杂度大幅提高,这个从量上家就能比较出来
3. 代码会变得脆弱,不易调试。使用反射咱们就在必定程度上绕开了编译器的语法代码会变得脆弱,不易调试。 使用反射咱们就在必定程度上绕开了编译器的语法检查,例如用反射去调一个对象的方法而该对象没有这个方法那么在编译时,编译器是没法发现的,只能到运行时由 JVM 抛出异常。