java - 方法与类型中的另一个方法具有相同的删除

标签 java generics

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

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

我得到 编译错误

Method add(Set) has the same erasure add(Set) as another method in type Test.

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

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

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

方法,但并非总是如此。

如果您想拥有两个接受这些参数的 constructors,这会更加烦人,因为您不能只更改其中一个 constructors 的名称。

最佳答案

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

这是为什么不允许这样做的说明,drawn from the JLS.假设,在泛型被引入 Java 之前,我写了一些这样的代码:

class CollectionConverter {
  List toList(Collection c) {...}
}

你扩展我的类(class),像这样:

class Overrider extends CollectionConverter{
  List toList(Collection c) {...}
}

在引入泛型之后,我决定更新我的库。

class CollectionConverter {
  <T> List<T> toList(Collection<T> c) {...}
}

您还没有准备好进行任何更新,所以请留下您的 Overrider单独上课。为了正确覆盖 toList()方法,语言设计者决定原始类型对任何泛型类型都是“覆盖等效的”。这意味着尽管您的方法签名不再正式等于我的父类(super class)的签名,但您的方法仍然会覆盖。

现在,时间过去了,您决定准备更新您的类(class)。但是你搞砸了一点,而不是编辑现有的原始 toList()方法,你添加一个像这样的新方法:

class Overrider extends CollectionConverter {
  @Override
  List toList(Collection c) {...}
  @Override
  <T> List<T> toList(Collection<T> c) {...}
}

由于原始类型的覆盖等效性,这两种方法都以有效的形式覆盖 toList(Collection<T>)方法。但当然,编译器需要解析单个方法。为了消除这种歧义,类不允许有多个重写等效的方法,即删除后具有相同参数类型的多个方法。

关键是这是一个语言规则,旨在保持与使用原始类型的旧代码的兼容性。这不是删除类型参数所需的限制;因为方法解析发生在编译时,将泛型类型添加到方法标识符就足够了。

关于java - 方法与类型中的另一个方法具有相同的删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1998544/

相关文章:

java - 启动 WLDF 控制台扩展时出现问题

java - 为什么是<T extends Comparable>而不是<T Implements Comparable>?

java - 具有可变参数类型的接口(interface)方法

generics - 编写没有大量样板类型约束的通用浮点代码

java - Java中的键值观察

java - eclipse - 如何为多个开发人员创建一个java项目(github)

java - Java 中具有继承性的 Varargs

java - 创建通用类列表

java - Ant 构建失败 - build.xml

java - 在数据流 2.x 中将 TableRow 转换为 JSON 格式字符串的最简单方法?