java中的反射和内省

原理

用反射你几乎可以做任何事情。Class对象的由来是将class文件读入内存,并为之创建一个Class对象。利用这个Class对象,你可以实现反射的功能。
在这里插入图片描述
对于Field的get和set。
最底层无非是计算偏移量,调用

sun.misc.Unsafe#getInt(java.lang.Object, long)

来获取变量值。
核心的类是FieldAccessor。
在这里插入图片描述

对于利用反射调用方法。底层对应的是

    private static native Object invoke0(Method var0, Object var1, Object[] var2);

在这里插入图片描述

			//var1是一个method对象
            NativeMethodAccessorImpl var2 = new NativeMethodAccessorImpl(var1);
            DelegatingMethodAccessorImpl var3 = new DelegatingMethodAccessorImpl(var2);
            var2.setParent(var3);
            return var3;

在构造完成DelegatingMethodAccessorImpl后,将其放在method对象的methodAccessor字段中。

注意事项

这里要注意一件非常tricky的事情。下面的代码是无法正常运行的

                    s.getClass().getDeclaredFields()[3].setAccessible(true);
                    try {
                        String gdl = (s.getClass().getDeclaredFields()[3].get(s).toString());
                        System.out.println(field.get(s).toString());
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                   System.out.println(GsonUtils.toJson(s));

要改成

                Field field = s.getClass().getDeclaredFields()[3];
                   field.setAccessible(true);
                   try {
                       String gdl = field.get(s).toString();
                       System.out.println(field.get(s).toString());
                   }catch (Exception e){
                       e.printStackTrace();
                   }
                  System.out.println(GsonUtils.toJson(s));

这是因为每次获取的field对象都是拷贝出来的不同对象。可以看下Field类copy方法的执行方式。

    Field copy() {
       // This routine enables sharing of FieldAccessor objects
       // among Field objects which refer to the same underlying
       // method in the VM. (All of this contortion is only necessary
       // because of the "accessibility" bit in AccessibleObject,
       // which implicitly requires that new java.lang.reflect
       // objects be fabricated for each reflective call on Class
       // objects.)
       if (this.root != null)
           throw new IllegalArgumentException("Can not copy a non-root Field");

       Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
       res.root = this;
       // Might as well eagerly propagate this if already present
       res.fieldAccessor = fieldAccessor;
       res.overrideFieldAccessor = overrideFieldAccessor;

       return res;
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值