Covariance and contravariance for wildcard types

Could you explain why this is possible:

import java.util.ArrayList;
import java.util.List;

public class Covariance {

    class A {
    }

    class B extends A {
    }

    class C extends A {
    }

    public void testSmth() throws Exception {
        List<? extends A> la = new ArrayList<A>();
        A a = la.get(0);
        // la.add(new B()); - doesn't compile

        List<? super B> lb = new ArrayList<A>();
        // lb.add(new A()); - doesn't compile
        lb.add(new B());
        Object object = lb.get(0);
    }

}

I don’t understand why it is impossible to add something to the covariant list la, but you can still add B to the contravariant list lb - but not from A to lb.

From my point of view, it should be possible to add everything that extends A to List. I see the only reason not to do this, because it is easy to add C to list B, for example

 List<B> lst = new ArrayList<B>();
 List<? extends A> lstB = lst;
 lstB.add(C); // this is valid for <? extends B> but list lst would contain instance of B.

Perhaps the same is true for contraception, for example

 List<B> lst = new ArrayList<B>;
 List<? super C> lstC = lst;
 lstC.add(new C());
 Object obj = lstC.get(0);

What I do not understand - why it is impossible to do

 B b = lstC.get(0);

Obviously, at this point, super C will be class B - Java does not allow multiple inheritance.

Also why does it forbid

 lstC.add(new B());

it is not clear to me.

+5
2

, super, :

import java.util.ArrayList;
import java.util.List;

public class Covariance {

    class A {
    }

    class B extends A {
    }

    class C extends A {
    }

    class D extends C {}

    public void testSmth() throws Exception {
        List<? super D> ld = new ArrayList<C>();
    }

}

, , ld D, , A.

+2

    List<? extends A> la = new ArrayList<C>();

C., B , .

+2

All Articles