4
import java.util.*;

// Let's define a self-referential type:
class SelfReferential<T extends SelfReferential<T>> {}

//A complete (i.e. not parameterized) subtype of SelfReferential:
class SubclassA extends SelfReferential<SubclassA> {}

//A partial (i.e. 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's 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

Bottom line, I can't specify the "reference cycle" in the extends clause.

Question: Is this a Java language limitation?

1 Answer 1

1

You're right that this isn't possible, just like declaring a variable with a self referencing type is impossible without wildcards or raw types. You wouldn't be able to directly instantiate a SubclassB for the same reason that you can't use it as a bound without a self-referencing type parameter.

See this post for more discussion on this limitation: Self bound generic type with fluent interface and inheritance

The bottom line is that GenericAnyB would need to be generic itself to use SubclassB as a bound:

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

Which just adds an extra step in the hierarchy before anything is usable:

class GenericB1 extends GenericAnyB<SubclassB1> { }   
class GenericB2 extends GenericAnyB<SubclassB2> { }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.