我的一位朋友在Java API(https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html)中找到了这个小窍门,
Class Enum<E extends Enum<E>>
通过阅读以下文章https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html我可以理解上述行在语法上的含义,但从给出的示例中我无法找出Enum类之外的用例(查看源代码)。
我想更多地了解上述问题可能出现的问题。
答案 0 :(得分:7)
例如,允许子类使用自己的类型
是有用的想象一下像
这样的课程class Node {
Node next;
}
如果您延长该课程,则会遇到Node
。
class SpecialNode extends Node {
void foo() {
// euwww
SpecialNode nextNode = (SpecialNode) this.next;
}
}
您也不能像
那样定义它class Node<T> {
T next;
}
因为这会允许T
的任何内容。您真的想要T
extends Node
,或者您无法再在Node
内使用Node
作为class Node<T extends Node<T>> {
T next;
}
。它适用于儿童班。
使用像
这样的递归边界class SpecialNode extends Node<SpecialNode> {
void foo() {
SpecialNode nextNode = this.next; // type-safe!
}
}
您将T限制为您自己或您自己的子类,然后允许您执行
{{1}}
这样,父类和子类都可以在其抽象级别上访问完全类型安全的所有内容。
答案 1 :(得分:4)
这个成语几乎总是意味着&#39; E应该是子类的类型&#39; 。例如,您可能会注意到枚举implements Comparable<E>
。
当课程延长时,你会得到类似的东西:
// E extends Enum<E> ┐
class AnEnum extends Enum<AnEnum> {...}
现在AnEnum也是Comparable<AnEnum>
而getDeclaringClass
返回Class<AnEnum>
。
我已经看到这个与curiously recurring template pattern相关的习语。目的是超类可以统一引用子类。
(由于Enum的子类是由编译器生成的,我不认为实际上有一个理由需要以这种方式声明Enum。它可能只是{{1} }。)
答案 2 :(得分:2)
通常,它可用于定义超类中的某些行为(例如,在Enum
中),这取决于特定于所讨论的类的子类型的类型信息(I actually asked a similar question a wee while ago)。