反射setAccessible()方法
java代碼中,常常將一個類的成員變量置為private
在類的外面獲取此類的私有成員變量的value時,需要注意:
測試類:
public class AccessibleTest { private String name; private Integer age; public AccessibleTest() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
Main類:
public class Main { public static void main(String[] args) throws IllegalAccessException { AccessibleTest accessibleTest = new AccessibleTest(); accessibleTest.setAge(20); accessibleTest.setName("zhangsan"); for (Field field : accessibleTest.getClass().getDeclaredFields()) { System.out.println(field); //AccessibleTest類中的成員變量為private,故必須進行此操作 field.setAccessible(true); //獲取當前對象中當前Field的value //field表示accessibleTest這個對象中的屬性 //field.get(accessibleTest)表示對象中這個屬性的值 System.out.println(field.get(accessibleTest)); } } }
console:
private java.lang.String com.winner.test.AccessibleTest.name zhangsan private java.lang.Integer com.winner.test.AccessibleTest.age 20
如果沒有在獲取Field之前調用setAccessible(true)方法,異常:
Exception in thread "main" java.lang.IllegalAccessException: Class com.winner.test.Main
can not access a member of class com.winner.test.AccessibleTest with modifiers "private"
當然在AccessibleTest類的內部(AccessibleTest的內部類除外)
進行如上操作則不需要調用setAccesible()方法
明顯 Accessible並不是標識方法能否訪問的. public的方法 Accessible仍為false
使用了method.setAccessible(true)后 性能有了20倍的提升
Accessable屬性是繼承自AccessibleObject 類. 功能是啟用或禁用安全檢查
JDK API中的解釋
引用
AccessibleObject 類是 Field、Method 和 Constructor 對象的基類。它提供了將反射的對象標記為在使用時取消默認 Java 語言訪問控制檢查的能力。對於公共成員、默認(打包)訪問成員、受保護成員和私有成員,在分別使用 Field、Method 或 Constructor 對象來設置或獲得字段、調用方法,或者創建和初始化類的新實例的時候,會執行訪問檢查。
在反射對象中設置 accessible 標志允許具有足夠特權的復雜應用程序(比如 Java Object Serialization 或其他持久性機制)以某種通常禁止使用的方式來操作對象。
setAccessible
public void setAccessible(boolean flag)
throws SecurityException
將此對象的 accessible 標志設置為指示的布爾值。值為 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查。值為 false 則指示反射的對象應該實施 Java 語言訪問檢查。
實際上setAccessible是啟用和禁用訪問安全檢查的開關,並不是為true就能訪問為false就不能訪問
Field類的get()方法:
public Object get(Object obj){ }
* @param obj object from which the represented field's value is to be extracted * @return the value of the represented field in object ; primitive values are wrapped in an appropriate * object before being returned
field.get(obj):
表示的含義是:
field是obj對象中的一個屬性(字段),get方法的返回值值obj對象中field這個屬性的值