[英]Java name clash error, a method has the same erasure as another method
[英]Java generics name clash , has the same erasure
我有超級Foo。 還有一個擴展它的類Bar。
public class Bar extends Foo
Foo中的功能:
protected void saveAll(Collection<?> many)
欄中的功能:
public void saveAll(Collection<MyClass> stuff) {
super.saveAll(stuff);
}
得到錯誤:
Name clash: The method saveAll(Collection<MyClass>) of type Bar has the same erasure as saveAll(Collection<?>) of type Foo but does not override it.
我究竟做錯了什么?
您使用不兼容的類型覆蓋saveAll
方法。 也許你想做的事情如下:
public class Bar extends Foo<MyClass>
函數在Foo<E>
protected void saveAll(Collection<E> many)
和Bar中的功能:
public void saveAll(Collection<MyClass> stuff) {
super.saveAll(stuff);
}
由於Java的類型擦除功能,JVM將無法知道它是具有參數化類型MyClass還是應該調用的第一個類型的方法。
如果可能或適用,我見過避免這種情況的最常用模式是將類Foo
更改為具有參數化類型:
public class Foo<T> {
protected void saveAll(Collection<T> many) {}
}
然后讓Bar簡單地為您的特定類型實現Foo
:
public class Bar extends Foo<MyClass> {
public void saveAll(Collection<MyClass> many) {
super.saveAll(many);
}
}
在運行時,參數類型將替換為Object
。 因此saveAll(Collection<?>)
和saveAll(Collection<MyClass>)
被轉換為saveAll(Collection)
。 這是一個名字沖突。 在這里查看詳細信息。
你可以這樣做:
public class Foo<T> {
protected void saveAll(Collection many) {
// do stuff
}
}
public class Bar extends Foo<MyClass> {
}
當編譯器編譯為字節代碼時,會發生一個名為Erasure的進程。 這將從集合中刪除類型信息。 我相信它將手動執行轉換等作為生成字節代碼的過程的一部分。 如果刪除類的通用部分(即<..>),則會看到有兩個saveAll方法。 錯誤是你有兩個保存所有方法將相同的簽名。 集合在字節代碼中具有類型對象。
嘗試刪除<..>,這可能會更清楚。 當你把<...>放回去時,請考慮方法的名稱。 如果它們不同則應編譯。
此外,我不認為這是一個休眠問題,所以應刪除此標記。 這是一個java泛型問題。
你在這里可以做的是鍵入類
public class Bar extends Foo<MyClass>
然后將方法類型賦予T
public void saveAll(Collection<MyClass> stuff) {
super.saveAll(stuff);
}
然后Foo的聲明會是這樣的
public abstract class Bar extends Foo<T> {
public void saveAll(Collection<T> stuff) {
}
您只需使用不同的簽名覆蓋方法。
什么是好主意是使用Joshua Bloch在Effective Java Second Edition中描述的PECS(生產者 - 擴展,消費者 - 超級)規則。
根據這條規則它應該是這樣的。
在Foo類中:
public class Foo<E>{
protected void saveAll(Collection<? super E> many){....}
protected void getAll(Collection<? extends E> many){....}
}
雖然現有答案是正確的,但是當您聲明實際類型不在“ extends
...”子句中但在實際類名中時,很容易發生此錯誤:
錯誤:
public class Bar<MyClass> extends Foo
{
...
}
正確:
public class Bar extends Foo<MyClass>
{
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.