【问题标题】:Method has the same erasure as another method in type - part 2方法与类型中的另一种方法具有相同的擦除 - 第 2 部分
【发布时间】:2017-10-21 05:15:08
【问题描述】:

我完全明白这个问题Method has the same erasure as another method in type 及其答案。请任何人帮助我理解以下内容?

努力消化,为什么下面的第二个代码sn-p会出现编译错误?

代码 1:编译良好​​p>

class Parent {
    public void set(Collection<Integer> c) { }
}

class Child extends Parent {
    public void set(Collection<Integer> c) {}
}

代码 2:子类中 set 方法的编译器错误。

class Parent {
    public void set(Collection<?> c) { }
}

class Child extends Parent {
    public void set(Collection<Integer> c) {}
}

编译器错误是

名称冲突: Child 类型的方法 set(Collection) 与 set(Collection) 的擦除相同 输入 Parent 但不覆盖它

【问题讨论】:

标签: java generics overriding


【解决方案1】:

因为您在第一个示例中的代码覆盖了父对象的方法,所以您最终会在子对象上设置一个方法:

 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)

【讨论】:

  • 这实际上是OP的问题。如果两者都像public void set(Collection c) 那样结束,那么应该没有错误。对吧?
  • 我已经编辑了我的答案以增加清晰度。它们最终都作为 set(Collection c) 结束,但是因为在第二种情况下它不是一个覆盖方法,它在子对象上出现两次。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 2017-12-09
    • 2011-10-18
    • 1970-01-01
    相关资源
    最近更新 更多