0

Idealized scenario

Let's imagine a scenario, with 2 classes like A and B where B extends A. I also have a third generic class C<T> with a method m(T t).

If I create a object C<C<A>> container and another object C<B> obj = new C<>(); why can't I run container.m(obj)?

Full code example

public class Test {
    class A {}
    class B extends A {}
    class C<T> {
        void m(T t) {}
    }
    void test() {
        C<C<A>> container = new C<>();
        C<B> obj = new C<>();

        container.m(obj);
    }
}

Practical case

This Issue becomes apparent with nested lists where the C<A> in my simplified example would be a a List<A>.

Oracle highlights some limitations of generics, but I can't find anything describing this issue and how to deal with it.

derdilla
  • 1
  • 1

1 Answers1

0

The issue

As VGR pointed out: C<B> doesn't extend C<A>.

So C<B> other than B itself, doesn't have any properties of C<A>.

This becomes more clear, when looking at what C<A> and C<B> generate: C<A> acts like a

class D {
    void m(A t) {}
}

while C<B> acts like a

class E {
    void m(B t) {}
}

When looking at it in this unraveled fashion, it becomes apparent, that class E doesn't extend class D.

The solution

As Elliott Frisch said, this can be avoided by changing C<A> to C<? extends A>.

Full working example:

public class Test {
    class A {}
    class B extends A {}
    class C<T> {
        void m(T t) {}
    }
    void test() {
        C<C<? extends A>> container = new C<>();
        C<B> obj = new C<>();
        container.m(obj);
    }
}
derdilla
  • 1
  • 1