我有一个抽象类A,B类是扩展A.具体类
除了B级的,但是Java文档调用B.class.getDeclaredMethods()返回Class A的方法签名的说,有些事情就不同 getDeclaredMethods()
“这其中包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。”
因此,从上述文档我期待方法foo(),它是由抽象父类继承不应从回getDeclaredMethods()
电话,但我得到方法foo(),它是由抽象父类继承的是从返回getDeclaredMethods()
调用。
import java.lang.reflect.*;
public class B extends A {
public static void main(String[] args) throws Exception {
Method[] methods = B.class.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i]);
}
}
}
abstract class A {
public void foo() {
}
}
有人可以解释我这种行为。
你这样做的原因是因为超有包级别的访问。如果您更改类的访问修饰符A
来public
(你需要把它放在它自己的文件),在额外的方法B.class.getDeclaredMethods()
消失。
(还要注意的是,abstract
修改后的类A
是红鲱鱼:会发生同样的事情时类A
不是抽象的)
这是一种解决方法在Java编译器用于反射一个错误:虽然foo
是一个公共方法,它在包范围的类定义A
。你可以反省类B
,找到方法,尝试使用反射来调用它,只得到一个IllegalAccessException
。
编译器将生成一个桥法类B
,这样就可以正确地反思invoke方法foo
。
如果你做的方法,这是最好的证明了foo
在A
一个final
方法,这使得它不可能解决这个反射错误(这是不可能要覆盖的方法)
类A
和B
使用软件包abc
和类C
是包def
。类C
试图反射性invoke方法foo
上类B
是公共的,但由于它是在非公共类中定义它失败A
。
异常在线程“主要” java.lang.IllegalAccessException:类def.C不能访问类abc.A的成员与修饰语“公众最终”
package abc;
public class B extends A {
}
class A {
public final void foo() {
}
}
package def;
import java.lang.reflect.Method;
import abc.B;
public class C {
public static void main(String[] args) throws Exception {
Method m = B.class.getMethod("foo");
m.invoke(new B());
}
}
只是除去final
从方法关键字foo
解决了该问题,因为编译器然后插入在类合成桥方法B
。
它的这个错误报告中解释说:
http://bugs.java.com/view_bug.do?bug_id=6342411
描述
下面的程序将失败,并此错误运行:
Exception in thread "main" java.lang.IllegalAccessException: Class refl.ClientTest can not access a member of class refl.a.Base with modifiers "public" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65) at java.lang.reflect.Method.invoke(Method.java:578) at refl.ClientTest.main(ClientTest.java:9)
========== test/refl/a/Base.java ========== 1 package refl.a; 2 3 class Base { 4 public void f() { 5 System.out.println("Hello, world!"); 6 } 7 } ========== test/refl/a/Pub.java ========== 1 package refl.a; 2 3 public class Pub extends Base {} ========== test/refl/ClientTest.java ========== 1 package refl; 2 import refl.a.*; 3 import java.lang.reflect.*; 4 5 public class ClientTest { 6 public static void main(String[] args) throws Exception { 7 Pub p = new Pub(); 8 Method m = Pub.class.getMethod("f"); 9 m.invoke(p); 10 } 11 }
评估
该提案是增加桥梁的方法在这些极少数情况下,以解决问题的反映,没有其他forseen修订或变通方法。具体而言,当一个公共方法是从非公共类继承到一个公共类,我们会产生一个桥接方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句