提高Java反射速度的方法以及对setAccessable的误解

37 篇文章 0 订阅
mercyblitz 写道
ouchxp 写道

再就是在执行反射之前执行field.setAccessible(true); 也可以提高JDK反射效率

这样可以提高效率?这个方法仅仅设置访问标识,让不能访问的成员可以访问。

keating 写道
ouchxp 写道
再就是在执行反射之前执行field.setAccessible(true); 也可以提高JDK反射效率

正如楼上mercyblitz所说,如private变量... 


在此澄清一下对于setAccessable的误解 
先看一个例子 
Java代码   收藏代码
  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就不能访问 

由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的 
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值