如果想要得到其个对象的成员属性,这个成员性质类型为包级私有内部类,而且该成员为私有,那么怎么得到该成员呢?
思路:
假设我们要研究的对象是TreeMap,我们想得到TreeMap对象的root
首先, TreeMap.class.getDeclaredClasses() 得到所有内部类,如root为内部类Entry,即clazz = TreeMap.class.getDeclaredClasses()[3]; 即可得到内部类类型
2、得到私有成员变量:Field rootf = TreeMap.class.getDeclaredField("root");因为其为私有,要设置访问权限rootf.setAccessible(true);
rootf 只是TreeMap中一个字段类型,与我们建立的对象没有关系,我们,我们要将其与物理对象相关联Object root = rootf.get(tree)(tree 为一个TreeMap对象)
3、类型与变量我们都得到了,那么要访问该类型里面都有什么属性是轻而易举的了,
接下来我们要反射Entry类型里面都有什么成员,然后利用里面的Filed绑定root就可以得到 root 里面的成员值了
Entrys = clazz.getDeclaredFields();
for(Field f:Entrys) {
f.setAccessible(true);
}
即 Entrys[0].get(root) 就可以得到 root 的Key值是多少,Entrys[2].get(root )就可以得到 root 的left 孩子
此方法是在研究TreeMap中有序列序列建树的过程中写的,也就是TreeMap中buildFromSorted方法
刚开始不知道其建立原理,于是就想得到树的结点,因为 Entry root 为私有,而内部类 Entry又为包级私有,都不能访问
因些只能利用反射,然后设置成员访问级别,具体方法见注释
package Trees;
import java.lang.reflect.Field;
public class TreeMapReflectRoot {
static TreeMap<Integer,Integer>tree;
static SortedMap<Integer,Integer>fill;
static Class<?> clazz; // 利用 getDeclaredClasses得到TreeMap中的内问类 Entry
static Field rootf; // 利用getDeclaredField 得到TreeMap 中的 root 成员
static Object root; // 得到 rootf.get(tree) 得到 tree变量的树根 root
static Field[] Entrys; // 内部类Entry 中的成员
private static void init()throws Exception {
tree = new TreeMap<Integer,Integer>();
fill = new TreeMap<Integer,Integer>();
fill.put(1,1);
fill.put(2,2);
fill.put(3,3);
fill.put(4,4);
fill.put(5,5);
fill.put(6,6);
fill.put(7,7);
fill.put(8,8);
fill.put(9,9);
fill.put(10,10);
tree.putAll(fill);
clazz = TreeMap.class.getDeclaredClasses()[3]; // get Entry Class
rootf = TreeMap.class.getDeclaredField("root"); // get Field root ;
rootf.setAccessible(true);
Entrys = clazz.getDeclaredFields(); // get Entry inner field;
for(Field f:Entrys) {
f.setAccessible(true);
}
root = rootf.get(tree);
}
public static Object key(Object obj)throws Exception {
return Entrys[0].get(obj);
}
public static Object value(Object obj)throws Exception{
return Entrys[1].get(obj);
}
public static Object left(Object obj)throws Exception{
return Entrys[2].get(obj);
}
public static Object right(Object obj)throws Exception{
return Entrys[3].get(obj);
}
public static Object parent(Object obj)throws Exception{
return Entrys[4].get(obj);
}
public static Object color(Object obj)throws Exception{
return (Boolean)Entrys[5].get(obj)==true?"Black":"Red";
}
public static void main(String args[])throws Exception{
init();
System.out.println(color(right(left(root))));
}
}