簡體   English   中英

類型擦除和覆蓋通用方法

[英]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.

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