1.import java.lang.reflect.InvocationTargetException;
2.import java.lang.reflect.Method;
3.
4.public class Main {
5. public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
6. Method m = A.class .getDeclaredMethod( "getName" , new Class[]{});
7. System.out.println(m.isAccessible());
8. //getName是public的,猜猜輸出是true還是false
9.
10. A a = new A();
11. a.setName("Mr Lee" );
12. long start = System.currentTimeMillis();
13. for ( int i= 0 ;i< 10000000 ;i++){
14. m.invoke(a, new Object[]{});
15. }
16. System.out.println( "Simple :" +(System.currentTimeMillis() - start));
17.
18. m.setAccessible(true ); //注意此處不同
19. long start1 = System.currentTimeMillis();
20. for ( int i= 0 ;i< 10000000 ;i++){
21. m.invoke(a, new Object[]{});
22. }
23. System.out.println("setAccessible(true) :" +( System.currentTimeMillis() - start1));
24. }
25.}
26.class A{
27. private String name;
28. public String getName() {
29. return name;
30. }
31. public void setName(String name) {
32. this .name = name;
33. }
34.}
測試結果
引用
false
Simple :4969
setAccessible(true) :250
明顯 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就不能通路