我有超类Foo。还有一个扩展它的类吧。
public class Bar extends Foo
Foo中的功能:
protected void saveAll(Collection<?> many)
Bar中的功能:
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.
我做错了什么?
答案 0 :(得分:18)
您正在使用不兼容的类型覆盖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);
}
答案 1 :(得分:8)
由于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);
}
}
答案 2 :(得分:4)
在运行时,参数类型将替换为Object
。
因此saveAll(Collection<?>)
和saveAll(Collection<MyClass>)
会转换为saveAll(Collection)
。这是一个名字冲突。
查看here了解详情。
你可以这样做:
public class Foo<T> {
protected void saveAll(Collection many) {
// do stuff
}
}
public class Bar extends Foo<MyClass> {
}
答案 3 :(得分:2)
当编译器编译为字节代码时,会发生一个名为Erasure的进程。这将从集合中删除类型信息。我相信它将手动执行转换等作为生成字节代码的过程的一部分。如果您删除了类的通用部分(即&lt; ..&gt;),那么您将看到有两个saveAll方法。错误是你有两个保存所有方法将相同的签名。集合在字节代码中具有类型对象。
尝试删除&lt; ..&gt;这可能会让它更清晰。当你把&lt; ...&gt;然后再考虑方法的名称。如果它们不同则应编译。
此外,我不认为这是一个休眠问题,所以应删除此标记。这是一个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) {
}
答案 4 :(得分:1)
您只需使用不同的签名覆盖方法。
最好使用Joshua Bloch撰写的Effective Java Second Edition中描述的PECS(Producer - Extends,Consumer - Super)规则。
根据这条规则它应该是这样的。
在Foo课程中:
public class Foo<E>{
protected void saveAll(Collection<? super E> many){....}
protected void getAll(Collection<? extends E> many){....}
}
答案 5 :(得分:0)
虽然现有答案是正确的,但当您声明实际类型不在&#34; extends
...&#34;时,很容易发生此错误。子句但在实际的类名中:
<强>错误:强>
public class Bar<MyClass> extends Foo
{
...
}
<强>正确:强>
public class Bar extends Foo<MyClass>
{
...
}