通过反射取得hashmap的值

来源:互联网 发布:蓝月传奇10转生数据 编辑:程序博客网 时间:2024/06/07 09:59

本人最近项目中在遇到个这个情况,需要做动态代理,invoke方法里的参数是object类型,实际参数是hashmap类型,需要从object类型里面取出key value键值对

首先hashmap和object是不能直接强制转换类型的,我采用反射取得数据

为了取得数据,首先得了解下hashmap的结构

在这里只讲点关键点,hashmap里面有个内部类,Node<K,Y>这个就是存放key value 的节点

 static class Node<K,V> implements Map.Entry<K,V> {        final int hash;        final K key;        V value;        Node<K,V> next;        Node(int hash, K key, V value, Node<K,V> next) {            this.hash = hash;            this.key = key;            this.value = value;            this.next = next;        }        public final K getKey()        { return key; }        public final V getValue()      { return value; }        public final String toString() { return key + "=" + value; }        public final int hashCode() {            return Objects.hashCode(key) ^ Objects.hashCode(value);        }        public final V setValue(V newValue) {            V oldValue = value;            value = newValue;            return oldValue;        }        public final boolean equals(Object o) {            if (o == this)                return true;            if (o instanceof Map.Entry) {                Map.Entry<?,?> e = (Map.Entry<?,?>)o;                if (Objects.equals(key, e.getKey()) &&                    Objects.equals(value, e.getValue()))                    return true;            }            return false;        }    }
transient Node<K,V>[] table;

可以看出hashmap的值存在属性table数组里面

然后看到node内部类属性有hash值,key,value,指向相同hash值的下一个节点的引用next

因为在hashmap里面key虽然不同,然后有可能经过hash值转换后生成的hash值相同,这个时候,相同的hash值的节点形成一个链表的形式


类似于这个模样,相同的hash值,存储的键值对node节点,以链表组装起来

现在需要将object类参数(实际上是hashmap类型,用父类引用指向子类对象)反射出里面的值

HashMap<String,Object> hashmap=new HashMap<String, Object>(); Class clsHashMap$Node = null;clsHashMap$Node = Class.forName("java.util.HashMap$Node");        //通过反射得到hashmap里面内部类node        Field[] fields = parameter.getClass().getDeclaredFields();        for(Field field:fields){       field.setAccessible(true);                if(field.getName()=="table"){            //遍历属性,当时table属性时候                 Object[] node= (Object[]) field.get(parameter);   //得到table属性值             for (Object object : node) {  //遍历if(object!=null){//有可能table数组有node为空,因为hash值特性try {    iteration(object, clsHashMap$Node, hashmap);   //递归} catch (NoSuchFieldException | SecurityException e) {e.printStackTrace();}}}                         }                             }


private void iteration(Object object,Class clsHashMap$Node,HashMap<String,Object> hashmap) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {Field key = clsHashMap$Node.getDeclaredField("key");     //获取node类里面的key属性Field value = clsHashMap$Node.getDeclaredField("value");  //获取node类里面value属性Field next = clsHashMap$Node.getDeclaredField("next");   //获取node类里面next属性key.setAccessible(true);value.setAccessible(true);next.setAccessible(true);//得到三个属性的属性值String strkey = key.get(object).toString();Object objValue = value.get(object);Object objNext = next.get(object);//判断next是否为空,不为空则递归if(objNext==null){hashmap.put(strkey, objValue);}else{iteration(objNext, clsHashMap$Node, hashmap);}}


最后,我们就讲hashmap里面的值全部反射出来


原创粉丝点击