类型擦除可防止过载,但允许覆盖

时间:2014-02-03 01:25:50

标签: java generics override overloading type-erasure

有人可以向我解释为什么Java中不允许这样做吗?我有这三个文件(StackExchange的剥离和简化):

一个超类,在我看来是泛型图。 type参数指示弧的表示方式:使用特定的Arc类,或使用指示唯一ID的Integers。

public interface Base<A> {
    public boolean removeArc(A arc);
}

子类,具有arc的特定实现。

public interface Sub<B> extends Base<Arc<B>> {
    @Override
    public boolean removeArc(Arc<B> arc);

    public Arc<B> removeArc(B value); //Removes an arc with this specific value.
}

弧实现。

public interface Arc<B> {
}

Netbeans在Sub中给出了以下编译时错误。在@Override:

name clash: removeArc(Arc<B>) in Sub overrides a method whose erasure is the same as another method, yet neither overrides the other
  first method: removeArc(B) in Sub
  second method: removeArc(A) in Base
  where B,A are type-variables:
    B extends Object declared in interface Sub
    A extends Object declared in interface Base

第二种方法:

name clash: removeArc(B) in Sub and removeArc(A) in Base have the same erasure, yet neither overrides the other
  where B,A are type-variables:
    B extends Object declared in interface Sub
    A extends Object declared in interface Base

问题似乎是removeArc(Arc<B>)removeArc(B)具有相同的删除,但我不明白为什么会发生这种情况。删除removeArc(Arc<B>)编译正常,不会对@Override发出警告,因此必须在Arc<B>中发现A等于Base

在这种情况下,为什么Java无法区分Arc<B>B

1 个答案:

答案 0 :(得分:3)

编译器在编译时删除泛型类。它将用限制级别取代占位符。

在这种情况下,Base会将A的任何实例替换为Object,而Sub会将B的任何实例替换为Object

这给出了冲突的方法

在基地public boolean removeArc(Object arc);

并在子public Arc removeArc(Object value);

如果你做了

public interface Base<A extends Arc<?>> {
    public boolean removeArc(A arc);
}

然后A的实例将替换为Arc,方法签名将不再发生冲突。