Uses of recursive type bounds
Asked Answered
I

3

6

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.

Imprimatur answered 27/11, 2014 at 18:38 Comment(0)
N
9

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.

Nannienanning answered 27/11, 2014 at 19:23 Comment(0)
R
4

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>.)

Render answered 27/11, 2014 at 19:23 Comment(1)
This is the right pattern used, not the one in my answer +1Thirtythree
T
2

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).

Thirtythree answered 27/11, 2014 at 18:44 Comment(4)
I don't think this question is the same as your question. (This one doesn't have anything to do with class literals.)Render
Yeah, I suppose I jumped a bit too far ahead. Nevertheless, it is still passing information about the subtype to the superclass, albeit only at compile time (e.g. for method signatures).Thirtythree
P.S. Should I delete the answer since I admit it's incorrect, or should it stay?-- I've never figured out this whole thing...Thirtythree
I would just edit out your first sentence. Your answer seems fine to me.Render

© 2022 - 2024 — McMap. All rights reserved.