Uses of recursive type bounds

前提是你 提交于 2019-12-04 03:23:29

问题


A friend of mine found this tidbit in the Java API (https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html),

Class Enum<E extends Enum<E>>

and by reading the following article https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html I could understand what the aforementioned line entailed syntactically but from the examples given I could not figure out a use case for this beyond the Enum class (reviewed the source).

I'd like to learn more about possible problems where the above may present a solution.


回答1:


It's for example useful to to allow subclasses to use their own type

Imagine a class like

class Node {
    Node next;
}

if you extend that class, you're stuck with Node.

class SpecialNode extends Node {
    void foo() {
        // euwww
        SpecialNode nextNode = (SpecialNode) this.next;
    }
}

You also can't just define it like

class Node<T> {
    T next;
}

because that would allow anything for T. You really want a T that extends Node or you can no longer use T as Node from within Node without casting. It would work for child classes though.

By using recursive bounds like

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

You limit T to yourself or subclasses of yourself which then allows you to do

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

That way both parent and child class can access everything on their abstraction level fully typesafe.




回答2:


This idiom almost always means 'E should be the type of the subclass'. For example, you might notice that Enum implements Comparable<E>.

When the class is extended, you get to something like:

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

Now AnEnum is also a Comparable<AnEnum> and getDeclaringClass returns a Class<AnEnum>.

I've seen this idiom related to the curiously recurring template pattern. The intent is that the superclass can refer to the subclass generically.

(Due to the fact that the subclass of Enum is generated by the compiler, I don't think there is actually a reason Enum in particular needed to be declared this way. It could have just been Enum<E>.)




回答3:


Generally it's useful for defining some behavior in a superclass (e.g. in Enum) which depends on type information specific to a subtype of the class in question (I actually asked a similar question a wee while ago).



来源:https://stackoverflow.com/questions/27177106/uses-of-recursive-type-bounds

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!