方法与类型中的另一种方法具有相同的擦除 - 第2部分

时间:2014-10-27 11:25:49

标签: java generics override

我完全得到了这个问题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但不覆盖它

2 个答案:

答案 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
    }
}

注意:如果您传递包含整数的集合,此代码将起作用,但是,此代码也适用于包含任何类型的集合,不限于(也不检查)整数。