繁体   English   中英

GetDeclaredMethods(java)中的问题

[英]Problem in the GetDeclaredMethods (java)

我的代码有一个小问题

我有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();}
}

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

通过这种方式

B b = new B();

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

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

System.out.print(m[i].getName());   
}

为什么输出是

foo

foo

为什么GetDeclaredMethods在A类中也找到foo? 我该如何解决?

谢谢

您遇到问题的原因是由于两个方法的协变量返回类型。 因为您有一个协变返回类型(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());
   }   
}

默认情况下, getDeclaredMethods()返回给定类的所有方法,以及它的父类和接口。 但是,通过Method对象,可以通过在Method上调用getDeclaringClass()来测试该Method属于哪个类。 因此,当您遍历所有Method对象时,可以添加逻辑以仅打印属于B类的方法。

Method[] m = b.getClass().getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
  if (m[i].getDeclaringClass().equals(B.class)) {
    System.out.print(m[i].getName());
  }
}

编辑:上面的代码无法按需工作-它返回B作为所有方法的声明类。 isSynthetic()方法似乎可以按预期工作,对于被覆盖的方法(来自A方法)返回true,但是对于来自B方法返回false。 因此,以下代码可能就是您想要的。

Method[] m = b.getClass().getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
  if (!m[i].isSynthetic()) {
    System.out.print(m[i]);
  }
}

因为B.foo和A.foo是不同的方法。 如果要覆盖方法A.foo,则方法B.foo必须返回类A。

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

这可能起作用:

A a = new A();
B b = new B();

List<Method> aMethods = Arrays.asList(a.getClass().getMethods());
List<Method> bMethods = Arrays.asList(b.getClass().getMethods());

for ( Method m : bMethods )
{
  if( ! aMethods.contains(m) )
  {
  //Your action code here
  }
}

当您说if(!aMethods.contains(m))是否包含按名称进行比较时? 参数类型? 返回值类型? 因为从通缉方法到不是唯一的区别是协方差返回类型...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM