Java 名称冲突:test2类型的方法add(Object)与HashSet类型的add(E)具有相同的擦除<;E>;但并没有覆盖它

Java 名称冲突:test2类型的方法add(Object)与HashSet类型的add(E)具有相同的擦除<;E>;但并没有覆盖它,java,generics,Java,Generics,导入java.util.* class A extends HashSet<Integer> { public boolean add(Object obj){ //compiler error return true; } } or class Abc <T> { public void add(T t){} //compiler error public void add(Obj

导入java.util.*

  class A extends HashSet<Integer> {
       public boolean add(Object obj){  //compiler error
        return true;
       }
    }
    or
   class Abc <T> {
    public void add(T t){}  //compiler error
    public void add(Object i){} //compiler error (can't overload?)
    }
类扩展了HashSet{
公共布尔添加(对象obj){//编译器错误
返回true;
}
}
或
Abc班{
public void add(T){}//编译器错误
public void add(Object i){}//编译器错误(不能重载?)
}
错误:名称冲突:test2类型的方法add(Object)与HashSet类型的add(E)具有相同的擦除,但没有覆盖它


我不知道上述错误背后的概念是什么,有人能建议我在哪里研究这个概念吗?

您是否尝试过使用Integer而不是Object obj,即

public boolean add(整数i)
{//编译器错误
返回true;
}

问题是,当您扩展Hashset时,您扩展的是整数Hashset,而不是泛型表单。因此,在子类中,add方法必须符合超类方法的签名,即

公共布尔加法(整数i){}

如果要从完全通用的Hashset实现进行扩展,请尝试使用扩展

public class MyHashset extends Hashset<?> {
公共类MyHashset扩展了Hashset{
}


然后您的add方法应该与Object一起使用。

这里使用的概念被调用
HashSet
定义方法
add(T)
,然后定义方法
add(Object)
。乍一看,人们可能会认为这是可以的;您的方法只是重载了
add
。然而,
T
的擦除是
Object
,因此两者具有相同的擦除签名

现在,如果您的方法正确地从
HashSet
中重写了该方法,那么这就没问题了。但要做到这一点,您应该使用
add(Integer)
,而不是
add(Object)
。您没有正确重写父方法,因此会将其报告为冲突,因为类不能提供具有相同签名的两个方法

您的
Abc
示例遵循相同的推理。您声明的两个方法具有相同的已擦除签名,因此它们冲突

进一步阅读 Angelika Langer仿制药常见问题解答

接口采集转换器{
收费表(c组);
无效方法(c类);
可比方法3(E);
可比方法4(U);
}
类重写器实现CollectionConverter{
@凌驾
公众名单收费表(c组){
返回null;
}
@凌驾
公共方法(c类){
}
@凌驾
公共可比方法3(对象o){
返回null;
}
@凌驾
公共可比方法4(整数u){
返回null;
}
}
这段代码运行良好。
在JLS中:子签名的概念旨在表示两个方法之间的关系,这两个方法的签名不完全相同,但其中一个可以覆盖另一个。具体来说,它允许签名不使用泛型类型的方法重写该方法的任何泛型版本。这一点很重要,这样库设计人员就可以独立于定义库的子类或子接口的客户机自由地生成方法。

我不能用另一个add(Object obj)方法重载吗?不,它会弄乱编译器所关心的哈希集。这是因为Set.get应该得到一个整数,但在插入任何随机对象的情况下,编译器无法知道该集是否包含整数。这是因为编译器保证get方法将返回一个整数。既然在你的例子中,编译器不能保证,它就不允许这样的行为。你不能这样做:
扩展Hashset
谢谢,我得到了它,但是很少,为什么先重写不工作呢example@user:你应该通读我发布的第二个FAQ链接,它彻底解释了这个复杂的主题。对于这样一个答案,完整的解释有点太多了。
interface CollectionConverter<U> {
    <T> List<T> toList(Collection<T> c);

    void fooMethod(Class<?> c);

    <E>Comparable<E> method3(E e);

    Comparable<U> method4(U u);
}

class Overrider implements CollectionConverter<Integer> {
    @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;
    }
}