Java反射AccessibleObject類的setAccessible方法
看下面的程式碼:
public class A { private int data=0; } import Java.lang.reflect.*; public class B { public static void main(String[] args) { A a1 = new A(); Field[] fields = a1.getClass().getDeclaredFields(); AccessibleObject.setAccessible(fields, true); try { 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()方法,我們可以實現對這些欄位的操作。但有的時候這將會成為一個安全隱患,為此,我們可以啟用java.security.manager來判斷程式是否具有呼叫
>java -Djava.security.manager ExampleExplorer Exception in thread "main" java.security.AccessControlException: access denied ( java.lang.reflect.ReflectPermission suppressAccessChecks) at java.security.AccessControlContext.checkPermission(Unknown Source)
getFields()與getDeclaredFields()區別:
getFields()只能訪問類中宣告為公有的欄位,私有的欄位它無法訪問.
getDeclaredFields()能訪問類中所有的欄位,與 public,private,protect無關
getMethods()與getDeclaredMethods()區別:
getMethods()只能訪問類中宣告為公有的方法,私有的方法它無法訪問,能訪問從其它類繼承來的公有方法.
getDeclaredFields()能訪問類中所有的欄位,與public,private,protect無關,不能訪問從其它類繼承來的方法
getConstructors()與getDeclaredConstructors()區別:
getConstructors()只能訪問類中宣告為public的建構函式.
getDeclaredConstructors()能訪問類中所有的建構函式,與public,private,protect無關
轉載:
http://blog.csdn.net/hzalan/article/details/1740794
http://blog.csdn.net/zhikun518/article/details/7055773