我完全得到了这个问题Method has the same erasure as another method in type及其答案。请任何人帮助我理解下面的内容吗?
尝试难以理解,为什么下面的第二个代码片段会出现编译错误?
代码1:编译正确
class Parent {
public void set(Collection<Integer> c) { }
}
class Child extends Parent {
public void set(Collection<Integer> c) {}
}
代码2:Child类中set
方法的编译器错误。
class Parent {
public void set(Collection<?> c) { }
}
class Child extends Parent {
public void set(Collection<Integer> c) {}
}
编译错误
名称冲突:Child类型的方法集(Collection)具有与set(Collection)相同的擦除 输入Parent但不覆盖它
答案 0 :(得分:1)
因为第一个示例中的代码是从父级覆盖方法,所以最终会在子对象上使用一个set方法:
public void set(Collection<Integer> c) {}
这显然很好。
在你的第二个例子中,你没有覆盖超类型的方法(因为覆盖方法不是你试图覆盖的方法的子签名)。因此,两种方法必须可以存在于子类型上。
//from parent:
public void set(Collection<?> c)
//from child:
public void set(Collection<Integer> c)
在类型擦除之后,不可能:
//from parent:
public void set(Collection c)
//from child:
public void set(Collection c)
答案 1 :(得分:0)
Java使用类型擦除。因此,在类型擦除之后,这两种方法看起来完全相同,但是,方法不会相互覆盖,因此您最终会得到两个具有相同签名的不同方法 - 这就是名称冲突的原因。这是不允许的,因为在运行时不知道应该使用哪一个。
如果您希望覆盖该方法,可以使用带有通配符捕获的辅助方法,如下所示:
class Parent {
public void set(Collection<?> c) { }
}
class Child extends Parent {
public void set(Collection<?> c) {
setHelper(c);
}
public <T> void setHelper(Collection<T> c) {
// use T instead of Integer in body of code
}
}
注意:如果您传递包含整数的集合,此代码将起作用,但是,此代码也适用于包含任何类型的集合,不限于(也不检查)整数。