GetDeclaredMethods(java)中的问题

Daz*_*zel 8 java reflection inheritance

我的代码中有一个小问题

我有2节课

public class A {

     public A foo(int a) {return new A();}
}

public class B extends A{

     public B foo(int x){ return new B();}
}
Run Code Online (Sandbox Code Playgroud)

现在在我的代码中我想只打印在B类中声明的方法

通过这种方式

B b = new B();

Method[] m = b.getClass().getDeclaredMethods();

for (int i = 0; i < m.length; i++) {

System.out.print(m[i].getName());   
}
Run Code Online (Sandbox Code Playgroud)

为什么输出

foo

foo
Run Code Online (Sandbox Code Playgroud)

为什么GetDeclaredMethods在A类中也找到了foo?我该怎么办呢?

谢谢

Yis*_*hai 18

您遇到问题的原因是因为两种方法的协变返回类型.因为你有一个协变返回类型(B的返回类型是B,而不是A,不像超类),引擎盖下的Java生成一个单独的方法,原始的返回类型充当1.5之前的字节码规范之间的桥梁.新的Java 1.5语言行为.

您应该用来检查的isBridge()方法是方法,因为它准确表达了您要排除的内容.所以最终的代码看起来像这样:

Method[] methods = B.class.getDeclaredMethods();

for (Method method : methods) {

   if (!method.isBridge()) {
       System.out.println(method.getName());
   }   
}
Run Code Online (Sandbox Code Playgroud)

  • @Dazel,基本上是isBridge标识由Java编译器完成的事情,以适应泛型引入字节码限制的Java语言特性.isSynthetic告诉你方法是否是合成生成的,哪种桥接方法是,但更多的东西也是如此,例如内部类的一些元素.因此,桥梁总是合成的,但合成并不总是桥梁.进一步考虑,合成可能是你最关心的 - 源代码中不存在该方法,你不关心为什么. (2认同)

Jim*_*ans 0

您可以调用 m.getDeclaringClass() 来查看它是来自 A 类还是 B 类的方法。