为什么在同一个类中使用以下两种方法是不合法的?

class Test{
   void add(Set<Integer> ii){}
   void add(Set<String> ss){}
}

我拿到compilation error

方法add(Set)与型式试验中的另一种方法具有相同的擦除add(Set).

虽然我可以解决这个问题,但我想知道为什么javac不喜欢这个.

我可以看到,在许多情况下,这两种方法的逻辑非常相似,可以用一种单一的方法来代替

public void add(Set<?> set){}

方法,但情况并非总是如此.

如果你想让两个constructors接受这些参数,这是非常恼人的,因为这样你就不能只更改其中一个constructors的名称.

推荐答案

此规则旨在避免仍然使用原始类型的遗留代码中的冲突.

下面举例说明了为什么不允许这样做,假设在将泛型引入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.

关键是,这是一条语言规则,旨在维护与使用原始类型的旧代码的兼容性.它不是类型参数擦除所需的限制;因为方法解析发生在编译时,所以向方法标识符添加泛型类型就足够了.

Java相关问答推荐

由于非私有方法未覆盖或实现超类型中的方法,因此无法使用“<>”

调用方法以try 并重新运行代码块

JavaFX 中的选择边框.想用 CSS 改变默认行为

将 android studio 升级到 Android Studio Chipmunk 后 | 2021.2.1 得到这个 gradle 问题

如何使用 Spring SAML2 禁用自动生成的页面 /login 和 /logout?

Java 流不打印出预期值

如何通过在 Java for Android 中以编程方式添加的 id 来获取组件

使用 URL 在底部导航栏项目图标内加载图像

如何为 JDK 17 编写 Github 工作流

使用 lib net.lingala.zip4j 时,Javafx Gradle 使异常 org.gradle.process.internal.ExecException 以非零退出值 1 结束

使用 Amazon Java SDK 无法识别 JSON 格式

我们应该如何设计不同内部微服务之间的通信

为什么 HttpServletRequest 的正文不能被多次读取?

使用 Comparable 接口禁止继承类型之间的比较

Spring OAuth 2.0 with jersey request:输入正确凭据后响应 401 Unauthorized

再次“过时的元素引用:元素未附加到页面文档”

如何在 Spring-Data-JDBC 中设置 fetch-size

org.apache.kafka.common.errors.SerializationException:未知的魔术字节

空手道:使用 JUnit5 的 run 者课程

如何在 Java 中创建包含运算符的变量?