Java Bound Mismatch in recursive generics/inheritance

92 views Asked by At

I have the following structure:

public abstract class A <E extends El, U extends A<E,U> > { ... }

public class B<E extends El> extends A<E, B<E> > { ... }

public abstract class C <E extends El, T extends A<E, T>> { ... }

My question is, why can I do this:

public class R extends C<El, B<El>> { ... }

but not

public class R <T extends B<El>> extends C<El, T> { ... }

Why is T (which extends B<El>) not a good substitute for B<El>?

The exception which I get is Bound mismatch: The type T is not a valid substitute for the bounded parameter <T extends A<El,T>> of the type C<E,T>

3

There are 3 answers

4
Tagir Valeev On BEST ANSWER

Try to declare A and C as follows

public abstract class A <E extends El, U extends A<E, ? super U>> {}
public abstract class C <E extends El, T extends A<E, ? super T>> {}
2
Bozydar Sobczak On
abstract class A <E extends El, U extends A<E, U> > {
}

class B<E extends El> extends A<E, B<E> > {
}

abstract class C <E extends El, T extends A<E, ? super T>> {
    public void X(T t, El a) {

    }
}


class R <T extends B<El>> extends C<El, T> {
}
0
newacct On

My question is, why can I do this:

public class R extends C<El, B<El>> { ... }

Because El extends El, and B<El> extends A<El, B<El>>

but not

public class R<T extends B<El>> extends C<El, T> { ... }

Because T does not extend A<El, T>. We know that T extends B<El>, and that B<El> extends A<El, B<El>>, and not A<El, T>. This declaration is in general unsafe.

It's impossible to give any suggestions without knowing what you do with these types inside the classes, and why you think the declaration is safe. For example, if it is known that A only serves as a "consumer" of U, then you can use a super bound and it will work:

public abstract class A<E extends El, U extends A<E, ? super U>> { ... }
public abstract class C<E extends El, T extends A<E, ? super T>> { ... }