Search code examples
javagenericsnested-generics

How do I use an extended generic type's type in a class?


Say I have some classes as follows:

class A { }

class B<TA extends A> { }

class C<TB extends B<? extends A>> {
    TA varOfTypeTA; // this throws an error obviously
}

How can I define the type of varOfTypeTA to be whatever TB's TA is?

I know I can define it as A varOfTypeTA, but I want it to be of type TA not A.

I tried forcing it to define TA with class C<TB extends B<TA extends A>> so I can use TA, but this throws a syntax error.

To clarify, if I then define these classes:

class Horse extends A { }

class HorseHerd extends B<Horse> { }

class HorseHerder extends C<HorseHerd> {
    Horse getFavoriteHorse() { return varOfTypeTA; } // varOfTypeTA defined in class C must be of type Horse, otherwise I have to cast
}

How can I make varOfTypeTA be of type Horse?


Solution

  • Also declare TA as a generic in the same class.

    public class C<TA extends A, TB extends B<TA>> {
        TA varOfTypeTA;
    }
    

    Then you can use TA in your class.

    class HorseHerder extends C<Horse, HorseHerd> {
        Horse getFavoriteHorse() { return this.varOfTypeTA; }
    }
    

    I was also surprised to learn that the order of the declaration doesn't seem to matter here. While I would prefer to declare TA first, I have found that this code also compiles:

    public class C<TB extends B<TA>, TA extends A> {
        TA varOfTypeTA;
    }