轉載:http://huoyanyanyi10.iteye.com/blog/1317614
提高java反射速度的方法method.setAccessible(true)
package com.chenshuyi.test; 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(); for (int i = 0; i < 10000000; i++) { m.invoke(a, new Object[] {}); } 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)的方式關閉安全檢查就可以達到提升反射速度的目的