天天看點

提高java反射速度的方法method.setAccessible(true)

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就不能通路