簡體   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