我尝试理解java中的泛型行为
我写了相同的代码:
共同部分:
class A1{}
class B1 extends A1{}
class C1 extends B1{}
案例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
案例2:
List<? super B1> list = new ArrayList<A1>();
list.add(new A1());//compile error
list.add(new B1());//valid
list.add(new C1());//valid
我认为我写了simmetrical代码。为什么我看到非模拟结果?
答案 0 :(得分:6)
List<? extends B1>
表示:未知类型的列表,它是或扩展B1。如果List<B1>
也扩展List<C1>
或List<Foo>
,则可以是Foo
,B1
或C1
。所以你不能在这样的列表中添加任何东西:
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>
您可以添加到此类列表的唯一内容是null。
List<? super B1>
表示:未知类型的列表,它是B1或B1
的超类或超接口。因此,它可以是List<B1>
,List<A1>
或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
但是,如果您尝试从这样的列表中获取元素,则无法保证其类型。唯一确定的是它是一个对象。
一般原则是PECS:Producer Extends,Consumer Super。这意味着当列表是生产者时(这意味着您希望从中获取元素),则应使用extends
。如果列表是使用者(这意味着您要向其中添加元素),则应使用super
。