[英]Why should I reference the base class when I can access all the methods just as well by referencing the subclass?
[英]Why do I get the base class methods via reflection when the subclass overrides them?
我有超級班:
class MyClass<T> {
public void setValue(T value){
//insert code
}
public T getValue(){
return null;
}
}
然后我有一個具體的推導
class MyClassImp extends MyClass<String> {
@Override
public void setValue(String value){
//insert code
}
@Override
public String getValue(){
return null;
}
}
關於MyClassImpl
反思:
Class clazz = MyClassImpl.class;
Method[] methods = clazz.getDeclaredMethods();
我得到了超類實現java.lang.Object getValue()
, void setValue(java.lang.Object)
和java.lang.String getValue()
, void setValue(java.lang.String)
。
根據Class.getDeclaredMethods()
vis-a- Class.getDeclaredMethods()
的Java文檔
返回一個Method對象數組,這些對象反映由此Class對象表示的類或接口聲明的所有方法。 這包括公共,受保護,默認(包)訪問和私有方法,但不包括繼承的方法。 返回的數組中的元素沒有排序,也沒有任何特定的順序。 如果類或接口未聲明任何方法,或者此Class對象表示基本類型,數組類或void,則此方法返回長度為0的數組。 類初始化方法
<clinit>
不包含在返回的數組中。 如果類聲明具有相同參數類型的多個公共成員方法,則它們都包含在返回的數組中。
為什么我得到超類型實現? 有什么我想念的嗎?
我需要這個的原因是我在基類實現上反射性地調用setValue
,我已經添加了一些特殊的注釋注釋,當然還有其他約束。
這是因為編譯的類實際上並申報setValue(Object)
。 該方法將轉換為String,然后調用強類型方法。 同樣, getValue(Object)
調用getValue(String)
。
基本上這是必需的,因為JVM並不真正了解泛型(至少不是深入的) - 為了在JVM級別覆蓋超類方法,它必須具有相同的簽名。
用javap -c MyclassImp
看一下這個類,你會看到額外的合成方法:
public java.lang.Object getValue();
Code:
0: aload_0
1: invokevirtual #3; //Method getValue:()Ljava/lang/String;
4: areturn
public void setValue(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #4; //class java/lang/String
5: invokevirtual #5; //Method setValue:(Ljava/lang/String;)V
8: return
}
正如Jon先前所說, 類型信息在運行時會丟失 。
因此,無論何時使用泛型,編譯器都會將所有這些“通用”繼承方法放在子類中。 非通用代碼也是如此。
我剛檢查過:當我從超類中刪除了通用相關代碼( <T>
部分)時,反射代碼在子類中給了我兩個方法,即使它覆蓋了它們。 這意味着文檔應該對通用相關代碼有點明確。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.