简体   繁体   English

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

[英]Method has the same erasure as another method in type - part 2

I completely get this question Method has the same erasure as another method in type and the answer to it. 我完全得到这个问题方法与类型中的另一种方法和它的答案具有相同的擦除 Please can anyone help me understand the below? 请任何人帮我理解下面的内容?

Trying hard to digest, why the 2nd code snippet below gives compiler error? 尝试难以消化,为什么下面的第二个代码片段会给编译器错误?

Code 1: Compiles fine 代码1:编译好

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

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

Code 2: Compiler Error at set method in Child class. 代码2:Child类中set方法的编译器错误。

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

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

Compiler Error is 编译器错误是

Name clash: The method set(Collection) of type Child has the same erasure as set(Collection) of type Parent but does not override it 名称冲突:Child类型的方法集(Collection)与Parent类型的set(Collection)具有相同的擦除但不覆盖它

Because your code in the first example is overriding the method from the parent, you end up with one set method on the child object: 因为第一个示例中的代码是从父级覆盖该方法,所以最终会在子对象上使用一个set方法:

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

Which is obviously fine. 这显然很好。

In your second example you are not overriding the method on the super-type (since the over-riding method is not a sub-signature of the method you're trying to override). 在你的第二个例子中,你没有覆盖超类型的方法(因为重载方法不是你试图覆盖的方法的子签名)。 Therefore it must be possible for both methods to exist on the child type. 因此,两种方法必须可以存在于子类型上。

//from parent:
public void set(Collection<?> c)

//from child:
public void set(Collection<Integer> c)

Which, after type erasure, isn't possible: 在类型擦除之后,不可能:

//from parent:
public void set(Collection c)

//from child:
public void set(Collection c)

Java uses type erasure. Java使用类型擦除。 So after type erasure, the two methods look identical, however, the methods do not override each other, so you'd end up with two different methods that have an identical signature - this is what gives the name clash. 因此在类型擦除之后,这两种方法看起来完全相同,但是,方法不会相互覆盖,所以你最终会得到两个具有相同签名的不同方法 - 这就是名称冲突的原因。 That's not allowed, because at runtime it would be unknown which one it should be used. 这是不允许的,因为在运行时不知道应该使用哪一个。

If you wish to override the method, you could use a helper method with wildcard capturing as follows: 如果要覆盖该方法,可以使用带有通配符捕获的辅助方法,如下所示:

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

Note: this code will work if you pass it a collection that contains Integers, however, this code will also work for a collection that contains any type as well, not limited to (nor checked for) Integers. 注意:如果您传递包含整数的集合,此代码将起作用,但是,此代码也适用于包含任何类型的集合,不限于(也不检查)整数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM