簡體   English   中英

Java Class.getMethods() 對覆蓋方法的行為

[英]Java Class.getMethods() behavior on overridden methods

在 Java 中使用反射編寫一個簡單的 JSON 序列化程序時,我被 Class.getMethods() 的行為弄得措手不及。 如果覆蓋方法的返回類型擴展了覆蓋方法的返回類型,則 Java Class.getMethods() 似乎返回覆蓋方法和覆蓋方法。
因此,例如給定接口:

static interface A {
  A x();
  A y();
}
static interface B extends A {
  B x();
  A y();
}

A.class.getMethods()按預期返回兩個方法的數組,但是B.class.getMethods()返回一個由 3 個方法組成的數組(這對我來說有點反直覺)。 在這 3 個中,1 對應於預期的y() ,但其余兩個分別對應於具有返回類型A的原始x()和具有返回類型Bx()的覆蓋版本。 這讓我覺得有點奇怪,但數組中的原始x()因為它無法從任何地方訪問。 無論如何我的問題是這樣的:
有沒有簡單的方法來獲取類方法的最專業版本的列表,而無需手動檢查覆蓋的方法並將它們過濾掉?

我的理解是,如果您過濾掉isBridge()返回true的方法,那么不需要的方法應該 go 消失。

這是 Java 如何實現協變返回類型的人工制品(橋方法也用於 generics,但這似乎與您的用例無關)。

編輯有趣的是,雖然這適用於類,但它似乎不適用於接口。 B的所有三種方法都標記為非橋接和非合成。 但是,如果我創建一個實現B的非抽象 class C ,則它A x()被標記為橋接和合成。

您所擁有的稱為“協變回報”。

正如 aix 指出的那樣,您似乎必須處理橋接方法。 閱讀: http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html (忽略關於泛型的文本)和這個: GetDeclaredMethods 中的問題(java)

One way is to say: B.class.getDeclaredMethods() , however, this will return only the methods declated in B. So, if you have C extends B implements A, C.class.getDeclaredMethods() wont return the methods that you沒有被覆蓋。

如果你想迭代,這樣做的好方法是

for (Method m: B.class.getMethods()) {
  if (m.getDeclaringClass() == Object.class || m.declaringClass() == A.class) 
    continue;
  // otherwise do some stuff
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM