Java field type for a generic recursive type value?

Given the class hierarchy, in which the base class defines a recursive type:

abstract class A<T extends A<T>> { } 

How can I declare another class (which should not be common in T, because such a T can change throughout the entire life cycle of an object) with a field that can contain any subclass of A?

The following does not work:

 public class B { //fails to compile, because the capture of ? is not sufficiently narrow private A<?> a; public <T extends A<T>> setA(T a) { this.a = a; } } 

- END OF QUESTION -

I noticed that some members of StackOverflow approach some complex questions: "Why do you do this in the first place?" The following is a justification for my use of this template - you may notice that the standard Java library also uses recursive self-tuning in its definition of the Enum class: Enum<E extends Enum<E>> . Similarly, you can ask this question as "how to define a field of type Enum<?> .

Justification example:

 abstract class A<T extends A<T>> { public abtract T self(); public B<T> bify(Bifyer bifyer) { return bifyer.bify(self()); } } 

with subclasses:

 class ASub1 extends A<ASub1> { public ASub1 self() { return this; } } class ASub2 extends A<ASub2> { public ASub2 self() { return this; } } 

associated with a hierarchy of parallel classes:

 abstract class B<T extends A<T>> { } class BSub1<T extends A<T>> implements B<T> { } class BSub2<T extends A<T>> implements B<T> { } //and others 

And with the generation of B instances driven by implementations of the Bifyer interface:

 interface Bifyer { B<ASub1> bify(ASub1 asub1); B<ASub2> bify(ASub2 asub2); } 

Implementations of this interface can return BSub1 or BSub2 for B. This is essentially a Visitor template application in which the visitor is Bideer, but unlike the standard Visitor, the accept method returns a value instead of void. This provides a modular structure in which various Bifyer implementations can be specified to provide alternative behaviors and return types for the Bify method — say one for each subclass of B.

+4
java generics visitor self-type
source share
1 answer

Should you anchor a wildcard ? below A , it should work:

 public class B { private A<? extends A> a; public <T extends A<T>> void setA(T a) { this.a = a; } } 
+4
source share

All Articles