【问题标题】:Type Bounds with Comparable Interface in JavaJava 中具有可比接口的类型边界
【发布时间】:2020-06-26 13:46:00
【问题描述】:
在 JDK 11 中,我创建了一个名为“Collection”的泛型类,以便为类型参数提供的任何类型都必须实现 Comparable 接口。目前类声明如下:
public class Collection <T extends Comparable<T>>
本来我以为类声明应该是这样的:
public class Collection <T implements Comparable<T>>
但 JDK 不喜欢这样。
所以我的问题是为什么类声明是前者而不是后者。难道我们不扩展类和实现接口吗?
【问题讨论】:
标签:
java
generics
inheritance
interface
【解决方案1】:
集合已在 java.util 中。用那个名字创建另一个类会让每个人都感到困惑;我建议你选择其他的。
泛型是关于一般类型的。使用了extends 这个词,这有点反映了该关键字在例如class Foo extends Bar 中的相同用法,但含义并不完全相同。关键是,规范说它是extends 而不是implements,不管后面是什么,而且在这个规范上没有什么比“规范这么说”更进一步的意义了。
【解决方案2】:
鉴于E 可能是一个类或一个接口,您是否想要implements E 或extends E?除非您想要第三个关键字(可能是上下文相关的),否则区分是没有意义的。
【解决方案3】:
关于边界声明的语法,在 Java 5 中添加泛型的语言架构师面临以下选择:
- 镜像声明结构(具有单独的
extends 和implements 边界),或
- 为上限类型选择一种形式(例如,
T extends Foo、T <: Foo 等)
后者(明智地,IMO)被视为更务实的选择,因为在声明类型变量时,超类型是类还是接口并不重要,并且具有要求的繁琐语法客户使用完全正确的关键字(并且会使像<T extends ArrayList implements Serializable> 这样的复合边界更加丑陋)可能会被视为只是使事情更难使用,而对代码的编写者或读者没有实际好处。
这样的决定通常是随着语言的发展而做出的,在这种情况下,与先例的严格一致性只会让事情变得更加困难而没有任何好处,因此语言设计者有时(在仔细考虑了两种替代方案的优缺点后)选择打破有先例是为了更好的结果。