开发者

Covariance and contravariance for wildcarded types

开发者 https://www.devze.com 2023-03-08 07:11 出处:网络
Can you please explain why it is possible to do: import java.util.ArrayList; import java.util.List; public class Covariance {

Can you please explain why it is possible to do:

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 not possible to add something to covariant list la, but it's still possible to add B to contravariant list lb - but not A to lb.

From my point of view, it should be possible to add everything extending A to List. I can see the only reason of not doing that because it is easy to add C to list of B, like

 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.

Probably the same is true for co开发者_运维百科ntravariance, e.g

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

What I don't understand - why it is not possible to do

 B b = lstC.get(0);

It is obvious that on this stage super of C would be class B - Java doesn't allow multiple inheritance.

Also why it prohibits

 lstC.add(new B());

it's not clear for me.


To understand what's going on with the super keyword, consider the following:

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>();
    }

}

Hopefully this illustrates that ld can be a List of any super type of D, even one that be a subclass of A.


consider

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

it's a list of C. if we could add B to it, that would violate the list type.

0

精彩评论

暂无评论...
验证码 换一张
取 消