泛型扩展和超级?differencies

gst*_*low 1 java generics inheritance wildcard

我试着理解java中的泛型行为

我写相同的代码:

共同部分:

class A1{}
class B1 extends A1{}
class C1 extends B1{}
Run Code Online (Sandbox Code Playgroud)

情况1:

        List<? extends B1> list = new ArrayList<C1>();
        list.add(new A1());// compile error
        list.add(new B1());//compile error
        list.add(new C1());//compile error
Run Code Online (Sandbox Code Playgroud)

案例2:

        List<? super B1> list = new ArrayList<A1>();
        list.add(new A1());//compile error
        list.add(new B1());//valid
        list.add(new C1());//valid
Run Code Online (Sandbox Code Playgroud)

我想我写的是simmetrical代码.为什么我看到非模拟结果?

JB *_*zet 6

List<? extends B1>表示:未知类型的列表,它是或扩展B1.所以它可能是a List<B1>,a List<C1>,或者List<Foo>if Foo也是extend B1C1.所以你不能在这样的列表中添加任何东西:

list.add(new A1); // incorrect, since A1 doesn't even extend B1
list.add(new B1()); // incorrect, since the list could be a List<C1>
list.add(new C1()); // incorrect, since the list could be a List<Foo>
Run Code Online (Sandbox Code Playgroud)

您可以添加到此类列表的唯一内容是null.

List<? super B1>表示:未知类型的列表,它是B1或超类或超级接口B1.所以它可能是a List<B1>,a List<A1>或a List<Object>(而不是别的).所以

list.add(new A1()); // incorrect, since the list could be a List<B1>, and A1 is not a B1
list.add(new B1()); // valid, since whatever the type of the list (B1, A1 or Object), B1 is of this type
list.add(new C1()); // valid, since whatever the type of the list (B1, A1 or Object), B1 is of this type
Run Code Online (Sandbox Code Playgroud)

但是,如果您尝试从这样的列表中获取元素,则无法保证其类型.唯一可靠的是它是一个对象.

一般原则是PECS:Producer Extends,Consumer Super.这意味着当列表是生产者时(这意味着你想从中获取元素),那么extends应该使用它.当列表是使用者(这意味着您要向其添加元素)时,super应该使用.