使用递归类型边界

时间:2014-11-27 18:38:20

标签: java extends

我的一位朋友在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类之外的用例(查看源代码)。

我想更多地了解上述问题可能出现的问题。

3 个答案:

答案 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)。