简体   繁体   English

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

[英]Type erasure prevents overloading, but allows overriding

Could anyone explain to me why this is not allowed in Java? 谁能向我解释为什么Java不允许这样做? I have these three files (stripped and simplified for StackExchange): 我有以下三个文件(为StackExchange剥离并简化):

A superclass, in my case for generic graphs. 对于我的通用图,是超类。 The type parameter indicates how arcs are represented: Either with a specific Arc class, or with Integers indicating unique IDs. 类型参数指示弧的表示方式:具有特定的弧类别,或者具有指示唯一ID的整数。

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

A subclass, with a specific implementation for 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.
}

The arc implementation. 弧的实现。

public interface Arc<B> {
}

Netbeans gives me the following compile-time errors in Sub. Netbeans在Sub中为我提供了以下编译时错误。 At @Override: 在@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

At the second method: 在第二种方法中:

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

The problem seems to be that removeArc(Arc<B>) and removeArc(B) have the same erasure, but I don't see why this is happening. 问题似乎是removeArc(Arc<B>)removeArc(B)具有相同的擦除,但是我不知道为什么会这样。 Removing removeArc(Arc<B>) compiles fine, without warning about the @Override , so it must realise that Arc<B> equals A in Base . 除去removeArc(Arc<B>)编译好,没有警告有关@Override ,所以它必须认识到, Arc<B>等于ABase

Why is Java unable to differentiate between Arc<B> and B in this case? 在这种情况下,为什么Java无法区分Arc<B>B

The compiler removes generic classes at compile time. 编译器在编译时删除泛型类。 It will replace the place holder with it's restricted class. 它将使用受限类替换占位符。

In this case Base will replace any instance of A with Object and Sub will replace any instance of B with Object . 在这种情况下Base将取代的任何实例AObjectSub将取代的任何实例BObject

this gives the conflicting methods 这给出了相互矛盾的方法

in Base public boolean removeArc(Object arc); 在Base public boolean removeArc(Object arc);

and in Sub public Arc removeArc(Object value); 在Sub public Arc removeArc(Object value);

if however you did 如果你做了

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

then the instances of A would be replaced with Arc and the method signatures would no longer conflict. 那么A的实例将被替换为Arc ,并且方法签名将不再冲突。

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

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