[英]Type erasure and overriding generic method
我對泛型的理解是,如果我有public void saveAll(Collection<? extends Object> stuff) {
則compile會將輸入參數的“最常見類型”確定為Collection<Object>
。 現在,我用下面的代碼重寫了通用方法,但是在重寫方法中出現了以下錯誤消息- Name clash: The method saveAll(Collection<? extends Object>) of type ChildWithGenericMethod has the same erasure as saveAll(Collection<Object>) of type ParentWithGenericMethod<T> but does not override it
public class ParentWithGenericMethod {
public void saveAll(Collection<Object> stuff) {
}
}
public class ChildWithGenericMethod extends ParentWithGenericMethod{
public void saveAll(Collection<? extends Object> stuff) {
}
}
我想知道的是,在類型擦除之后,這些方法的外觀如何,我認為它們看起來像是public void saveAll(Collection stuff) {
因此,我應該能夠重寫,因為如果我不使用泛型,那我可以像這樣覆蓋
請注意,我知道在使用“ javap”編譯后可以看到字節碼,但是它沒有告訴我在“類型擦除”之后這些方法的外觀。
public void saveAll(Collection stuff) {
那么子類為什么會覆蓋錯誤,因為使用public void saveAll(Collection<Object> stuff) {
它會通過覆蓋規則。
值得記住運行時與編譯時分派。
一秒鍾拿走仿制葯。
public class Parent {
public void saveAll(Object x) {
}
}
public class Child extends Parent {
public void saveAll(String x) {
}
}
public String x = "hello";
public Object y = new Integer(334);
public Object z = "goodbye";
public Child c1 = new Child();
c1.saveAll(x); // invokes Child.saveAll
c1.saveAll(y); // invokes Parent.saveAll
c1.saveAll(z); // invokes Parent.saveAll even though z contains a String
現在將泛型重新納入故事。
public class Child<T extends Object> extends Parent {
public void saveAll(T x) {
}
}
在這里,saveAll重載而不是覆蓋父級的saveAll。
用異物代替T嗎? 並沒有真正改變這一點-編譯器正在嘗試創建一個重載父方法的方法,但隨后意識到它不能分派編譯時類型。
[編輯,請參閱Lew Block對原始內容的評論:編譯器需要在類型擦除之前確定子方法是重寫還是重載父方法]
如果在類型擦除之后,這兩個方法都變為public void saveAll(Collection stuff){那么子類為什么會覆蓋錯誤,因為使用public void saveAll(Collection stuff){它會通過覆蓋規則。
問題(再次參見Lew Bloch的評論)是重寫是在類型擦除之前確定的。 在類型擦除之前,父方法和子方法具有不同的簽名,因此編譯器將它們創建為重載方法,而不是覆蓋方法。 在類型擦除之后,編譯器意識到它處於綁定中,因為它現在具有兩個具有相同簽名的方法,並且不知道如何分派。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.