此规则旨在避免仍然使用原始类型的遗留代码中的冲突.
下面举例说明了为什么不允许这样做,假设在将泛型引入Java之前,我编写了如下代码:
class CollectionConverter {
List toList(Collection c) {...}
}
你扩展了我的课堂,就像这样:
class Overrider extends CollectionConverter{
List toList(Collection c) {...}
}
在引入泛型之后,我决定更新我的库.
class CollectionConverter {
<T> List<T> toList(Collection<T> c) {...}
}
你还没有准备好做任何更新,所以你把你的Overrider
门课留下.为了正确重写toList()
方法,语言设计者决定原始类型与任何泛型类型"重写等价".这意味着,尽管您的方法签名在形式上不再等于我的超类签名,但您的方法仍然覆盖.
现在,随着时间的推移,你决定你已经准备好更新你的课程了.但是你把事情搞砸了一点,你没有编辑现有的原始toList()
方法,而是选择了一种新方法,如下所示:
class Overrider extends CollectionConverter {
@Override
List toList(Collection c) {...}
@Override
<T> List<T> toList(Collection<T> c) {...}
}
Because of the override equivalence of raw types, both methods are in a valid form to override the toList(Collection<T>)
method. But of course, the compiler needs to resolve a single method. To eliminate this ambiguity, classes are not allowed to have multiple methods that are override-equivalent—that is, multiple methods with the same parameter types after erasure.
关键是,这是一条语言规则,旨在维护与使用原始类型的旧代码的兼容性.它不是类型参数擦除所需的限制;因为方法解析发生在编译时,所以向方法标识符添加泛型类型就足够了.