1700447732
1700447733
if(!method.isAccessible()){
1700447734
1700447735
method.setAccessible(true);
1700447736
1700447737
}
1700447738
1700447739
//执行方法
1700447740
1700447741
method.invoke(obj, args);
1700447742
1700447743
此段代码已经成为了习惯用法:通过反射方式执行方法时,必须在invoke之前检查Accessible属性。这是一个好习惯,也确实应该如此,但方法对象的Accessible属性并不是用来决定是否可访问的,看如下代码:
1700447744
1700447745
public class Foo{
1700447746
1700447747
public final void doStuff(){
1700447748
1700447749
System.out.println(“Do Stuff……”);
1700447750
1700447751
}
1700447752
1700447753
}
1700447754
1700447755
定义一个public类的public方法,这是一个没有任何限制的方法,按照我们对Java语言的理解,此时doStuff方法可以被任何一个类访问。我们编写一个客户端类来检查该方法是否可以反射执行:
1700447756
1700447757
public static void main(String[]args)throws Exception{
1700447758
1700447759
//反射获取方法
1700447760
1700447761
Method m1=Foo.class.getMethod(“doStuff”);
1700447762
1700447763
//打印出是否可访问
1700447764
1700447765
System.out.println(“Accessible=”+m1.isAccessible());
1700447766
1700447767
//执行方法
1700447768
1700447769
m1.invoke(new Foo());
1700447770
1700447771
}
1700447772
1700447773
很简单的反射操作,获得一个方法,然后检查是否可以访问,最后执行方法输出。让我们来猜想一下结果:因为Foo类是public的,方法也是public,全部都是最开放的访问权限,那么Accessible也应该等于true。但是运行结果却是:
1700447774
1700447775
Accessible=false
1700447776
1700447777
Do Stuff……
1700447778
1700447779
为什么Accessible属性会等于false?而且等于false了还能执行?这是因为Accessible的属性并不是我们语法层级理解的访问权限,而是指是否更容易获得,是否进行安全检查。
1700447780
1700447781
我们知道,动态修改一个类或方法或执行方法时都会受Java安全体系的制约,而安全的处理是非常消耗资源的(性能非常低),因此对于运行期要执行的方法或要修改的属性就提供了Accessible可选项:由开发者决定是否要逃避安全体系的检查。
[
上一页 ]
[ :1.700447732e+09 ]
[
下一页 ]