一个类中,private的属性或方法,如何对这些属性进行读写操作或方法进行调用呢,答案就是反射。
最近在写单元测试用例时,发现通过反射来测试一些private的方法或设置private的属性非常实用。
先看定义一个类,其中有一个private的属性和一个private的方法,并且构造函数也是一个private
public class Context {
private String name;
private Context(){}
private void process(String name, List<Integer> dataList){
// doSomeThing
}
}
当然,实际情况不会有这样的对象,这里只是为了演示用。接下来,首先要构造这个对象,如果有public的构造函数,我们知道可以这样写:
Class.forName("packageName.className").newInstance();
或者
ClassLoader cl = Thread.currentThread().getContextClassLoader();
cl.loadClass("packageName.className").newInstance();
以上构造方法默认调用public的无参构造函数,如果构造函数是private的呢?那么可以这样写:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> clazz = cl.loadClass("packageName.className");
Constructor<?> c = clazz.getDeclaredConstructor();
// set accessible
c.setAccessible(true);
Context obj = (Context) c.newInstance(new Object[]{});
获取私有域的方法:
Field field = obj.getClass().getDeclaredField("name");
// set accessible
field.setAccessible(true);
// set value
field.set(obj, "kkk");
// 也可以获取所有的域
Field[] fields = obj.getClass().getDeclaredFields();
获取私有方法并执行:
Method method = obj.getClass().getDeclaredMethod("process", new Class<?>[]{String.class, List.class});
// set accessible
method.setAccessible(true);
// invoke
method.invoke(obj, new Object[]{"kkk", new ArrayList()});
// 也可以获取所有的方法
Method[] methods = obj.getClass().getDeclaredMethods();
上面用到了Class、Constructor、Field、Method这几个反射相关的类。
还有很多好用的方法,在JDK的API文档中有详细的解释