TreeMap--利用反射得到TreeMap中树的结构,也就是得到root

如果想要得到其个对象的成员属性,这个成员性质类型为包级私有内部类,而且该成员为私有,那么怎么得到该成员呢?

思路:

假设我们要研究的对象是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))));
	}
	
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值