为什么第二个例子编译成功

时间:2016-06-14 09:24:10

标签: java generics

import java.util.*;    

class Test
{
    public static class Base
    {           
    }

    public static class Derived1
        extends Base
    {               
    }

    public static class Derived2
        extends Base
    {               
    }

    public static void main (String[] args)
    {
        //Example1.
        List<? extends Base> e = new ArrayList<Base>();
        e.add(new Derived1()); //this won't compile

        //Example2.
        List<? super Base> b = new ArrayList<Base>();
        b.add(new Derived1()); //this compiles
    }
}

2 个答案:

答案 0 :(得分:3)

可以为{p> List<? super Base> b分配List<Base>List<Object>。可以向两者添加Derived1实例,因此b.add(new Derived1())语句通过编译。

另一方面,List<? extends Base> e可能会被分配List<Derived2>,因此编译器不允许向其添加Derived1实例。

答案 1 :(得分:1)

请参阅What is PECS (Producer Extends Consumer Super)?

如果要向List<T>添加内容,则列表是您要添加的内容的使用者。因此,列表元素的类型T必须与您尝试添加或超类型的内容相同。