JDK源碼(十六):Field

java.lang.reflect.Field提供類或接口的單個字段的信息和動態訪問。反射字段可以是類(靜態)字段或實例字段。Field類提供了獲取和設置某個類的字段的屬性值。

在java.lang.Class獲取Field對象的方法總共有四個:

1. getDeclaredField(String name);

返回一個 Field 對象,name參數表示字段的名稱(包括私有的)。

2. getDeclaredFields();

返回 Field 對象的一個數組,表示的類或接口所聲明的所有字段(包括私有字段)。

3. getField(String name);

返回一個 Field 對象,表示的類或接口的指定公共成員字段,參數name爲字段名稱。

4. getFields();

返回一個包含某些 Field 對象的數組,表示的類或接口的所有可訪問公共字段。

類名

package java.lang.reflect;
public final
class Field extends AccessibleObject implements Member

變量(部分)

Field類的作用是獲取和設置成員變量的屬性值,所以Field類提供了一系列的get和set方法。

public static void main(String[] args) throws Exception {

        Student student = Student.class.newInstance();
        Field name = Student.class.getDeclaredField("name");
        //private屬性,設置可訪問
        name.setAccessible(true);
        name.set(student, "jdk");
        Object o = name.get(student);
        System.out.println(o);
    }

get(Object obj)

    @CallerSensitive
    public Object get(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).get(obj);
    }

第一步和Method類一樣,先檢查訪問權限,getFieldAccessor也和Method類中的MethodAccessor一樣,先獲取字段的訪問器FieldAccessor。

    private FieldAccessor getFieldAccessor(Object obj)
        throws IllegalAccessException
    {
        boolean ov = override;
        FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
        return (a != null) ? a : acquireFieldAccessor(ov);
    }

    // 
    private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) {
        // 先檢查是否已經創建
        FieldAccessor tmp = null;
        if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck);
        if (tmp != null) {
            if (overrideFinalCheck)
                overrideFieldAccessor = tmp;
            else
                fieldAccessor = tmp;
        } else {
            // 創建一個並賦值給root
            tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
            setFieldAccessor(tmp, overrideFinalCheck);
        }

        return tmp;
    }

在newFieldAccessor里根據字段的修飾符和類型生成相對應的FieldAccessor,從而調用各自的get和set方法。

static FieldAccessor newFieldAccessor(Field var0, boolean var1) {
        Class var2 = var0.getType();
        boolean var3 = Modifier.isStatic(var0.getModifiers());
        boolean var4 = Modifier.isFinal(var0.getModifiers());
        boolean var5 = Modifier.isVolatile(var0.getModifiers());
        boolean var6 = var4 || var5;
        boolean var7 = var4 && (var3 || !var1);
        if (var3) {
            UnsafeFieldAccessorImpl.unsafe.ensureClassInitialized(var0.getDeclaringClass());
            if (!var6) {
                if (var2 == Boolean.TYPE) {
                    return new UnsafeStaticBooleanFieldAccessorImpl(var0);
                } else if (var2 == Byte.TYPE) {
                    return new UnsafeStaticByteFieldAccessorImpl(var0);
                } else if (var2 == Short.TYPE) {
                    return new UnsafeStaticShortFieldAccessorImpl(var0);
                } else if (var2 == Character.TYPE) {
                    return new UnsafeStaticCharacterFieldAccessorImpl(var0);
                } else if (var2 == Integer.TYPE) {
                    return new UnsafeStaticIntegerFieldAccessorImpl(var0);
                } else if (var2 == Long.TYPE) {
                    return new UnsafeStaticLongFieldAccessorImpl(var0);
                } else if (var2 == Float.TYPE) {
                    return new UnsafeStaticFloatFieldAccessorImpl(var0);
                } else {
                    return (FieldAccessor)(var2 == Double.TYPE ? new UnsafeStaticDoubleFieldAccessorImpl(var0) : new UnsafeStaticObjectFieldAccessorImpl(var0));
                }
            } else if (var2 == Boolean.TYPE) {
                return new UnsafeQualifiedStaticBooleanFieldAccessorImpl(var0, var7);
            } else if (var2 == Byte.TYPE) {
                return new UnsafeQualifiedStaticByteFieldAccessorImpl(var0, var7);
            } else if (var2 == Short.TYPE) {
                return new UnsafeQualifiedStaticShortFieldAccessorImpl(var0, var7);
            } else if (var2 == Character.TYPE) {
                return new UnsafeQualifiedStaticCharacterFieldAccessorImpl(var0, var7);
            } else if (var2 == Integer.TYPE) {
                return new UnsafeQualifiedStaticIntegerFieldAccessorImpl(var0, var7);
            } else if (var2 == Long.TYPE) {
                return new UnsafeQualifiedStaticLongFieldAccessorImpl(var0, var7);
            } else if (var2 == Float.TYPE) {
                return new UnsafeQualifiedStaticFloatFieldAccessorImpl(var0, var7);
            } else {
                return (FieldAccessor)(var2 == Double.TYPE ? new UnsafeQualifiedStaticDoubleFieldAccessorImpl(var0, var7) : new UnsafeQualifiedStaticObjectFieldAccessorImpl(var0, var7));
            }
        } else if (!var6) {
            if (var2 == Boolean.TYPE) {
                return new UnsafeBooleanFieldAccessorImpl(var0);
            } else if (var2 == Byte.TYPE) {
                return new UnsafeByteFieldAccessorImpl(var0);
            } else if (var2 == Short.TYPE) {
                return new UnsafeShortFieldAccessorImpl(var0);
            } else if (var2 == Character.TYPE) {
                return new UnsafeCharacterFieldAccessorImpl(var0);
            } else if (var2 == Integer.TYPE) {
                return new UnsafeIntegerFieldAccessorImpl(var0);
            } else if (var2 == Long.TYPE) {
                return new UnsafeLongFieldAccessorImpl(var0);
            } else if (var2 == Float.TYPE) {
                return new UnsafeFloatFieldAccessorImpl(var0);
            } else {
                return (FieldAccessor)(var2 == Double.TYPE ? new UnsafeDoubleFieldAccessorImpl(var0) : new UnsafeObjectFieldAccessorImpl(var0));
            }
        } else if (var2 == Boolean.TYPE) {
            return new UnsafeQualifiedBooleanFieldAccessorImpl(var0, var7);
        } else if (var2 == Byte.TYPE) {
            return new UnsafeQualifiedByteFieldAccessorImpl(var0, var7);
        } else if (var2 == Short.TYPE) {
            return new UnsafeQualifiedShortFieldAccessorImpl(var0, var7);
        } else if (var2 == Character.TYPE) {
            return new UnsafeQualifiedCharacterFieldAccessorImpl(var0, var7);
        } else if (var2 == Integer.TYPE) {
            return new UnsafeQualifiedIntegerFieldAccessorImpl(var0, var7);
        } else if (var2 == Long.TYPE) {
            return new UnsafeQualifiedLongFieldAccessorImpl(var0, var7);
        } else if (var2 == Float.TYPE) {
            return new UnsafeQualifiedFloatFieldAccessorImpl(var0, var7);
        } else {
            return (FieldAccessor)(var2 == Double.TYPE ? new UnsafeQualifiedDoubleFieldAccessorImpl(var0, var7) : new UnsafeQualifiedObjectFieldAccessorImpl(var0, var7));
        }
    }
get和set方法最終都是調用底層native方法getXXX和putXXX方法獲取和設置字段值。

更多精彩內容請關注微信公衆號:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章