【问题标题】:Uses of recursive type bounds递归类型边界的使用
【发布时间】:2014-11-27 18:38:20
【问题描述】:

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

我想详细了解以上可能提供解决方案的可能问题。

【问题讨论】:

    标签: java extends


    【解决方案1】:

    例如,允许子类使用自己的类型很有用

    想象一个像这样的类

    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 中使用 T 作为 Node 而不进行强制转换。不过它适用于子类。

    通过使用递归边界,如

    class Node<T extends Node<T>> {
        T next;
    }
    

    您将 T 限制为您自己或您自己的子类,然后您可以这样做

    class SpecialNode extends Node<SpecialNode> {
        void foo() {
            SpecialNode nextNode = this.next; // type-safe!
        }
    }
    

    这样,父类和子类都可以完全类型安全地访问其抽象级别的所有内容。

    【讨论】:

      【解决方案2】:

      这个成语几乎总是意味着'E 应该是子类的类型'。例如,您可能会注意到 Enum implements Comparable&lt;E&gt;

      当类被扩展时,你会得到类似的东西:

      //         E extends Enum<E> ┐
      class AnEnum extends Enum<AnEnum> {...}
      

      现在 AnEnum 也是一个 Comparable&lt;AnEnum&gt; 并且 getDeclaringClass 返回一个 Class&lt;AnEnum&gt;

      我见过这个与curiously recurring template pattern 相关的成语。目的是超类可以泛指子类。

      (由于 Enum 的子类是由编译器生成的,我认为实际上没有理由特别需要以这种方式声明 Enum。它可能只是 Enum&lt;E&gt;。)

      【讨论】:

      • 这是使用的正确模式,而不是我的答案 +1 中的模式
      【解决方案3】:

      通常,它对于定义超类(例如Enum)中的某些行为很有用,这取决于特定于所讨论类的子类型(I actually asked a similar question a wee while ago)的类型信息。

      【讨论】:

      • 我觉得这个问题和你的问题不一样。 (这与类文字没有任何关系。)
      • 是的,我想我跳得太远了。尽管如此,它仍在将有关子类型的信息传递给超类,尽管只是在编译时(例如,用于方法签名)。
      • P.S.我应该删除答案,因为我承认它不正确,还是应该保留?--我从来没有弄清楚这整件事......
      • 我只想删掉你的第一句话。你的回答对我来说似乎很好。
      猜你喜欢
      • 2017-03-22
      • 2015-01-25
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多