wmcoo 发表于 2013-2-3 11:22:44

反射无视私有

1.私有构造函数的调用:
主要的类:java.lang.reflect.Constructor

首先要拿到构造方法,具体如下:
Class clazz = Class.forName("Bean"); 
Constructor[]  cons = clazz.getDeclaredConstructors();
这样拿到的cons数组保存着所有的这个类的构造函数,包括私有的和公有的。
迭代并调用con.toGenericString()可以拿到每个构造方法的全限定名(带修饰符,带参数)。
如果要拿单个构造方法,可以调用getDeclaredConstructor(Class args);来拿,只要参数匹配了就可以得到,如果没有参数,则传null即可。  

然后需要调用Constructor的方法setAccessible设置为true,表示允许使用私有构造函数。这个方法是父类AccessibleObject的方法,这个类的自类有Constructor, Field, Method分别代表构造函数,成员变量,和成员方法。也就是说使用这个方法,可以访问类的所有的方法、变量、构造函数。  

最后,使用Constructor的newInstance方法就可以把对象创建出来了:
Bean bean = (Bean)con.newInstance(Object args);
没有参数的构造函数可以传null进去。 

2.调用私有的方法:
主要的类:java.lang.reflect.Method

首先还是要拿到那个私有的方法,可以调用
Method[] ms =  clazz.getDeclaredMethods();来拿到所有的方法的集合。
也可以拿某个单独的方法:getDeclaredMethod(String name, Class... parameterTypes)匹配名字和参数的方法会被拿到,方法若没有参数传null.
同样可以调用toGenericString()看全限定名。

然后同样需要调用setAccessible(true)来设置可以方法私有方法。

最后,就可以使用method.invoke(bean, Object args);来调用这个方法。两个参数分别是对象,和这个方法的参数。

3.调用私有成员变量,也叫字段。
主要类:java.lang.reflect.Field

首先还是要拿到要使用的字段:
还是两种,拿全部:Field[] fs =  clazz.getDeclaredFields();
拿某个:clazz.getDeclaredField(String fieldName);

老步骤:setAccessible(true)

最后, f.get(obj) ,就能拿到传入对象的私有变量。

测试:
<div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 http://yh-private.iteye.com/images/icon_copy.gif
页: [1]
查看完整版本: 反射无视私有