Java泛型名称冲突,具有相同的擦除

Jaa*_*nus 26 java generics

我有超级Foo.还有一个扩展它的类Bar.

public class Bar extends Foo
Run Code Online (Sandbox Code Playgroud)

Foo中的功能:

protected void saveAll(Collection<?> many)
Run Code Online (Sandbox Code Playgroud)

栏中的功能:

public void saveAll(Collection<MyClass> stuff) {
   super.saveAll(stuff);
}
Run Code Online (Sandbox Code Playgroud)

得到错误:

 Name clash: The method saveAll(Collection<MyClass>) of type Bar has the same erasure as saveAll(Collection<?>) of type Foo but does not override it.
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Mat*_*arz 20

saveAll使用不兼容的类型覆盖该方法.也许你想做的事情如下:

public class Bar extends Foo<MyClass>
Run Code Online (Sandbox Code Playgroud)

功能 Foo<E>

protected void saveAll(Collection<E> many)
Run Code Online (Sandbox Code Playgroud)

和Bar中的功能:

public void saveAll(Collection<MyClass> stuff) {
   super.saveAll(stuff);
}
Run Code Online (Sandbox Code Playgroud)


Joe*_*erg 8

由于Java的类型擦除功能,JVM将无法知道它是具有参数化类型MyClass还是应该调用的第一个类型的方法.

如果可能或适用,我见过避免这种情况的最常用模式是将类更改Foo为具有参数化类型:

public class Foo<T> {
    protected void saveAll(Collection<T> many) {}
}
Run Code Online (Sandbox Code Playgroud)

然后让Bar简单地Foo为您的特定类型实现:

public class Bar extends Foo<MyClass> {
    public void saveAll(Collection<MyClass> many) {
        super.saveAll(many);
    }
}
Run Code Online (Sandbox Code Playgroud)


gon*_*ard 5

在运行时,参数类型被替换为Object. 所以saveAll(Collection<?>)saveAll(Collection<MyClass>)被转化为saveAll(Collection)。这是名称冲突。详情请看这里

你可以这样做:

public class Foo<T> {
    protected void saveAll(Collection many) {
        // do stuff
    }
}

public class Bar extends Foo<MyClass> {
}
Run Code Online (Sandbox Code Playgroud)