天天看點

提高Java反射速度的方法以及對setAccessable的誤解

mercyblitz 寫道

ouchxp 寫道

再就是在執行反射之前執行field.setaccessible(true); 也可以提高jdk反射效率

這樣可以提高效率?這個方法僅僅設定通路辨別,讓不能通路的成員可以通路。

keating 寫道

正如樓上mercyblitz所說,如private變量... 

在此澄清一下對于setaccessable的誤解 

先看一個例子 

java代碼  

提高Java反射速度的方法以及對setAccessable的誤解

import java.lang.reflect.invocationtargetexception;  

import java.lang.reflect.method;  

public class main {  

    public static void main(string[] args) throws securityexception, nosuchmethodexception, illegalargumentexception, illegalaccessexception, invocationtargetexception {  

        method m = a.class.getdeclaredmethod("getname", new class[]{});  

        system.out.println(m.isaccessible());  

                //getname是public的,猜猜輸出是true還是false  

        a a = new a();  

        a.setname("mr lee");  

        long start = system.currenttimemillis();  

        for(int i=0;i<10000000;i++){  

            m.invoke(a, new object[]{});  

        }  

        system.out.println( "simple              :" +(system.currenttimemillis() - start));  

        m.setaccessible(true);//注意此處不同  

        long start1 = system.currenttimemillis();  

        system.out.println("setaccessible(true) :"+( system.currenttimemillis() - start1));  

    }  

}  

class a{  

    private string name;  

    public string getname() {  

        return name;  

    public void setname(string name) {  

        this.name = name;  

測試結果 

引用

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

由于jdk的安全檢查耗時較多.是以通過setaccessible(true)的方式關閉安全檢查就可以達到提升反射速度的目的