[英]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()
和具有返回類型B
的x()
的覆蓋版本。 這讓我覺得有點奇怪,但數組中的原始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.