Java subclass issue with typical self-referencing type

import java.util.*; // Let define a self-referential type: class SelfReferential<T extends SelfReferential<T>> {} //A complete (ie not parameterized) subtype of SelfReferential: class SubclassA extends SelfReferential<SubclassA> {} //A partial (ie parameterized) subtype of SelfReferential: class SubclassB<T extends SubclassB<T>> extends SelfReferential<T> {} //Two complete subtypes of SubclassB class SubclassB1 extends SubclassB<SubclassB1> {} class SubclassB2 extends SubclassB<SubclassB2> {} //Now let define a generic type over SelfReferential: class Generic<T extends SelfReferential<T>> {} //No problem creating a subtype for A, B1 or B2 class GenericA extends Generic<SubclassA> {} class GenericB1 extends Generic<SubclassB1> {} class GenericB2 extends Generic<SubclassB2> {} //We can also defined a parameterize type for specific types extending SubclassB class GenericB<T extends SubclassB<T>> extends Generic<T> {} //However, it does not seem possible to define a non-parameterized subtype of Generic of ANY subtype of SublassB //My goal is to provide a type alias for GenericB<? extends SubclassB<?>> to avoid //having to mention it everywhere in the code. This is like providing an alias for ArrayList<String> using class ArrayListOfString extends ArrayList<String> {} //Unsucessful attempts: //class GenericAnyB extends Generic<SubclassB> {} //ERROR: bound mismatch //class GenericAnyB extends Generic<SubclassB<?>> {} //ERROR: bound mismatch //class GenericAnyB extends Generic<? extends SubclassB<?>> {} //ERROR: invalid syntax: a supertype cannot specify any wildcard //class GenericAnyB extends Generic<SubclassB<? extends SubclassB>> {} //ERROR: bound mismatch //class GenericAnyB extends Generic<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB>>>>>> {} // well... //class GenericAnyB extends <T extends SubclassB<T>> Generic<T> {} //ERROR: this syntax is illegal 

On the bottom line, I cannot specify a "reference loop" in the extends clause.

Question: Is this a limitation of the Java language?

+4
source share
1 answer

You are right that this is impossible, just as declaring a variable with a self-implemented type is impossible without wildcards or raw types. You could not directly create an instance of SubclassB for the same reason that you cannot use it as a binding without a parameter of the type of self-regulation.

See this post to learn more about this limitation: Native generic type with smooth interface and inheritance

The bottom line is that GenericAnyB must be shared to use SubclassB as a binding:

 class GenericAnyB<T extends SubclassB<T>> extends Generic<T> { } 

This simply adds an extra step to the hierarchy before anything can be used:

 class GenericB1 extends GenericAnyB<SubclassB1> { } class GenericB2 extends GenericAnyB<SubclassB2> { } 
+1
source

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


All Articles