java 反射setAccessible()方法的使用



首先看下面的代碼:
public class A
{
    private int data=0;
}


public class B
{
    public static void main(String[] args)
    {
        A a1 = new A();

       //獲得A類中所有定義的屬性
        Field[] fields = a1.getClass().getDeclaredFields();

       //對所有屬性設置訪問權限  當類中的成員變量爲private時 必須設置此項
        AccessibleObject.setAccessible(fields, true);

     /*****

      個人覺得只要Field.setAccessible(true); 之後,即使是final關鍵字標示過得屬性也可以有訪問權限!這樣的反射會改變JAVA的結構,

       甚至你的代碼可維護性,你完全可以 改別的代碼裏面的值 ,所以通過反射能做一些讓你無法想象的東西。。

       for(f : fields){

      //對單個屬性設置訪問權限

      f.setAccessible(true);

      }

     ******/


        try
        {

            //   獲取當前對象a1中當前Field的value  
            System.out.println(fields[0].toString() + "=" + fields[0].get(a1));
            fields[0].setInt(a1, 150);
            System.out.print(fields[0].toString() + "=" + fields[0].get(a1));
        } catch (IllegalAccessException ex1)
        {
        } catch (IllegalArgumentException ex1)
        {
        }
    }
}
以上代碼的輸出結果爲:
private int reflectiontest.A.data=0
private int reflectiontest.A.data=150

在這個過程中對象a1的private類型字段值被修改了,這是否算是破壞了Java的訪問規則呢? 

 

一般情況下,我們並不能對類的私有字段進行操作,利用反射也不例外,但有的時候,例如要序列化的時候,我們又必須有能力去處理這些字段,這時候,我們就需要調用AccessibleObject上的setAccessible()方法來允許這種訪問,而由於反射類中的Field,Method和Constructor繼承自AccessibleObject,因此,通過在這些類上調用setAccessible()方法,我們可以實現對這些字段的操作。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章