1. 程式人生 > >5、獲取Class中的欄位

5、獲取Class中的欄位

5、獲取Class中的欄位

5.1 getField(String name) 只獲取共有的欄位

  • 返回一個 Field物件,它反映此表示的類或介面的指定公共成員欄位 類物件。
/**
 * 獲取位元組碼檔案的欄位
 */
@Test
public void getFieldDemo() throws Exception {

    Class clazz = Class.forName("com.hw.bean.Person");
    Field name = clazz.getField("name");
    System.out.println(name);
}

執行:

報錯,原因是欄位是私有的。

要反映的欄位由以下演算法確定。 讓C成為由該物件表示的類或介面:

  • 如果C宣告一個具有指定名稱的公共欄位,那就是要反映的欄位。
  • 如果在上述步驟1中沒有找到欄位,則將該演算法遞迴地應用於C的每個直接超級介面。直接超級介面按照它們被宣告的順序被搜尋。
  • 如果在上面的步驟1和2中沒有找到欄位,並且C具有超類S,則該演算法在S上遞迴地呼叫。如果C沒有超類,則丟擲NoSuchFieldException 。

5.2 getDeclaredField(String name) 只獲取本類 但包含私有

@Test
public void getFieldDemo() throws Exception {

    Class clazz = Class.forName("com.hw.bean.Person");

    Field field = // clazz.getField("name");
            clazz.getDeclaredField("name");
    Object instance = clazz.newInstance();
    Object age = field.get(instance);
}

執行:

還是報錯,不能訪問私有的

5.3 java.lang.reflect.AccessibleObject

  • AccessibleObject類是Field,Method和Constructor物件的基類。 它提供了將反射物件標記為在使用它時抑制預設Java語言訪問控制檢查的功能。
  • 當使用Fields,Methods或Constructors來設定或獲取欄位,呼叫方法,或建立和初始化新的類例項時,執行訪問檢查(對於public,預設(包)訪問,受保護和私有成員)。
5.3.1 setAccessible(boolean flag) 暴力訪問
  • 將此物件的 accessible標誌設定為指示的布林值。
@Test
public void getFieldDemo() throws Exception {

    Class clazz = Class.forName("com.hw.bean.Person");

    Field field = // clazz.getField("name");
            clazz.getDeclaredField("name");
    // 對私有欄位的訪問取消許可權檢查。暴力訪問
    field.setAccessible(true);
    Object instance = clazz.newInstance();
    // 對欄位賦值
    field.set(instance,"張四");
    Object name = field.get(instance);
    System.out.println(name);
}

執行:


本章節原始碼: ReflectDemo3