名称冲突:类型为test2的方法add(Object)与类型为HashSet 的add(E)具有相同的擦除,但不会覆盖它
import java.util。*;
class A extends HashSet { public boolean add(Object obj){ //compiler error return true; } } or class Abc { public void add(T t){} //compiler error public void add(Object i){} //compiler error (can't overload?) }
错误:名称冲突:类型为test2的方法add(Object)具有与HashSet类型的add(E)相同的擦除但不覆盖它
我不知道上面背后的概念是什么错误可以任何人建议我可以在哪里研究这个概念?
这里的概念称为类型擦除 。 HashSet
定义了一个方法add(T)
,并定义了一个方法add(Object)
。 人们可能会认为这是可以的; 您的方法只是重载add
。 然而, T
的擦除是Object
,因此两者具有相同的擦除签名。
现在,如果你的方法从HashSet
正确地覆盖了方法,那HashSet
。 但要这样做,你应该使用add(Integer)
而不是add(Object)
。 您没有正确覆盖父方法,因此它被报告为冲突,因为类不能提供具有相同签名的两个方法。
您的Abc
示例遵循相同的推理。 您声明的两个方法具有相同的擦除签名,因此它们会发生冲突。
进一步阅读
Angelika Langer Generics FAQ
- 方法何时覆盖其超类型的方法?
- 非generics子类型的方法是否可以覆盖generics超类型的方法?
interface CollectionConverter { List toList(Collection c); void fooMethod(Class> c); Comparable method3(E e); Comparable method4(U u); } class Overrider implements CollectionConverter { @Override public List toList(Collection c) { return null; } @Override public void fooMethod(Class c) { } @Override public Comparable method3(Object o) { return null; } @Override public Comparable method4(Integer u) { return null; } }
这段代码效果很好。 在JLS中:子签名的概念旨在表达两个方法之间的关系,这两个方法的签名不相同,但其中一个方法可能会覆盖另一个方法。 具体来说,它允许一种方法,其签名不使用generics类型来覆盖该方法的任何泛化版本。 这很重要,因此库设计者可以独立于定义库的子类或子接口的客户端自由地生成方法。
您是否尝试使用Integer而不是Object obj ie
public boolean add(Integer i) { //compiler error return true; }
问题是,当您扩展Hashset时,您将扩展Integer Hashset而不是genericsforms。 因此,在子类中,add方法必须符合超类方法的签名
public boolean add(Integer i){}
如果您想从完全通用的Hashset实现扩展,请尝试使用
public class MyHashset extends Hashset> {
}
然后你的add方法应该与Object一起使用。