友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

72. Field

属性操作方法 Field#set(Object obj, Object value)Field#get(Object obj) 底层都是委托到 jdk.internal.reflect.FieldAccessor 实现。

FieldAccessor 接口有很多的实现,FieldAccessor 接口实例是通过 jdk.internal.reflect.ReflectionFactory 这个工厂构造的:

jdk.internal.reflect.ReflectionFactory
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    public FieldAccessor newFieldAccessor(Field field, boolean override) {
        checkInitted();

        Field root = langReflectAccess.getRoot(field);
        if (root != null) {
            // FieldAccessor will use the root unless the modifiers have
            // been overrridden
            if (root.getModifiers() == field.getModifiers() || !override) {
                field = root;
            }
        }
        return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
    }

最终委托到 UnsafeFieldAccessorFactory#newFieldAccessor()

UnsafeObjectFieldAccessorImpl 中除了 get(Object obj)set(Object obj, Object value) 方法,其他方法都是直接抛出 IllegalArgumentException。而 get(Object obj)set(Object obj, Object value) 底层分别依赖于 jdk.internal.misc.UnsafeputObject(obj, fieldOffset, value)getObject(obj, fieldOffset) 方法。而属性的内存偏移地址是在 UnsafeObjectFieldAccessorImpl 的父类 UnsafeFieldAccessorImpl 的构造函数中计算出来的。

属性反射操作 FieldsetXXgetXX 方法最终委托到 jdk.internal.misc.UnsafeputXXgetXX 方法,而属性的内存偏移地址是通过 jdk.internal.misc.UnsafestaticFieldBase()staticFieldOffsetobjectFieldOffset 几个方法计算的。