1700447696
1700447697
}
1700447698
1700447699
//静态内部类
1700447700
1700447701
static class Foo{
1700447702
1700447703
void doStuff(){}
1700447704
1700447705
}
1700447706
1700447707
此段代码运行后的输出如下:
1700447708
1700447709
Exception in thread”main”java.lang.NoSuchMethodException:Client$Foo.doStuff()
1700447710
1700447711
at java.lang.Class.getMethod(Class.java:1605)
1700447712
1700447713
at Client.main(Client.java:10)
1700447714
1700447715
该异常是说m2变量的getDeclaredMethod方法没有找到doStuff方法,明明有这个方法呀,为什么没有找到呢?这是因为getMethod方法获得的是所有public访问级别的方法,包括从父类继承的方法,而getDeclaredMethod获得是自身类的所有方法,包括公用(public)方法、私有(private)方法等,而且不受限于访问权限。
1700447716
1700447717
其他的getDeclaredConstructors和getConstructors、getDeclaredFields和getFields等与此相似。Java之所以如此处理,是因为反射本意只是正常代码逻辑的一种补充,而不是让正常代码逻辑产生翻天覆地的变动,所以public的属性和方法最容易获取,私有属性和方法也可以获取,但要限定本类。
1700447718
1700447719
那现在问题来了:如果需要列出所有继承自父类的方法,该如何实现呢?简单,先获得父类,然后使用getDeclaredMethods,之后持续递归即可。
1700447720
1700447721
1700447722
1700447723
1700447725
编写高质量代码:改善Java程序的151个建议 建议103:反射访问属性或方法时将Accessible设置为true
1700447726
1700447727
Java中通过反射执行一个方法的过程如下:获取一个方法对象,然后根据isAccessible返回值确定是否能够执行,如果返回值为false则需要调用setAccessible(true),最后再调用invoke执行方法,具体如下:
1700447728
1700447729
Method method=……;
1700447730
1700447731
//检查是否可以访问
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{
[
上一页 ]
[ :1.700447696e+09 ]
[
下一页 ]