Using recursive type boundaries

My friend 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 reading the following article https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html I could understand what the above line was syntactically meant, but from the above examples I could not understand the use case for this outside the class Enum (source considered).

I would like to know more about possible problems where a solution can be presented above.

+5
source share
3 answers

This, for example, is useful for allowing subclasses to use their own type.

Imagine a class like

 class Node { Node next; } 

if you extend this class, you are stuck in Node .

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

You also cannot just define it as

 class Node<T> { T next; } 

because it will allow anything for T Do you really want T to be extends Node , or you can no longer use T like Node from Node without casting. However, this will work for child classes.

Using recursive bounds such as

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

You restrict T to yourself or subclassing yourself, which then allows you to do

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

Thus, both the parent and child classes can access everything at their level of abstraction, completely typeafe.

+4
source

This is usually useful for defining some behavior in a superclass (for example, in Enum ), which depends on the type information related to the subtype of the class in question ( I actually asked a similar question question earlier ).

+2
source

This idiom almost always means that "E must be a type of subclass." For example, you may notice that Enum implements Comparable<E> .

When the class is extended, you get something like:

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

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

I saw this idiom associated with a curiously repeating pattern template . The goal is that the superclass can refer to the subclass as a whole.

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

+2
source

Source: https://habr.com/ru/post/1207838/


All Articles