Home > Enterprise >  Generics-why can you add a child of T to a List<? super T>
Generics-why can you add a child of T to a List<? super T>

Time:09-28

Taken from https://stackoverflow.com/a/19231762/1498827

public class Test {

    public class A {}

    public class B extends A {}

    public class C extends B {}

    public void testContraVariance(List<? super B> myBlist) {
        B b = new B();
        C c = new C();
        myBlist.add(b);
        myBlist.add(c);
        A a = myBlist.get(0); // does not compile
    }
}

If myBlist accepts a super type of B ,which means B or up, then why can you also add a child to it as in myBlist.add(c) ?

CodePudding user response:

I think the question is specifically about the meaning of List<? super B>. The OP wrote "myBlist accepts ... B or up" and I think this is the root of the misunderstanding. List<? super B> does not mean a list that can only contain elements of type B or of a supertype of B.

Instead, List<? super B> is a list whose type parameter is B or is a supertype of B. Given the type hierarchy in the question, and this declaration:

public void testContraVariance(List<? super B> myBlist)

then myBlist can be a List<B>, a List<A>, or a List<Object>. Any of these types can contain a C. That's why myBlist.add(c) works.

CodePudding user response:

Every C is-a B. You should be comfortable with the notion of assigning an instance of C to a variable of type B:

B c = new C();

From there, it should not be surprising that this is valid:

List<? super B> myBlist = new ArrayList<Object>();
myBlist.add(c);
  • Related