2014-09-02 58 views
2

我使用下面的代码,并试着添加子对象名单:Java的泛型类型的通配符扩展允许添加仅空

List<? extends Parent> list = new ArrayList<Child>(); 
list.add(new Child()); //error: The method add(capture#1-of ? extends Parent) in the type  List<capture#1-of ? extends Parent> is not applicable for the arguments (Child) 

class Parent{ 
} 
class Child extends Parent{ 
} 

我想知道为什么这里的编译器错误抛出?

+1

如果你想解决,替换'List <?将Parent>'扩展为'列表'。如果你想了解谷歌协变和逆变。 – talex 2014-09-02 09:11:44

+0

为什么要将'list'的类型声明为'List <?如果你不知道它是什么意思,那么扩展Parent>'如果你创建一个'ArrayList '你为什么不把它保存为'List '? – Holger 2014-09-02 09:29:19

+1

*为什么要将列表的类型声明为List <?如果你不知道它是什么意思,那么扩展Parent> *,@Holger,这就是人们如何学习,通过做事情:) – sanbhat 2014-09-02 09:37:20

回答

3

如果你去通过甲骨文的文档规定的Generic Guidelines,这几样表声明都倾向于只读(没有写操作可以执行)

从页面

报价

List<? extends ...>定义的列表可以非正式地认为是 只读,但这不是一个严格的保证。

按照您的例子,让我们假设Child2Child3extends Parent,然后

List<? extends Parent>列表可以是任何这些子类的列表。添加特定的子元素会导致运行错误,因此编译器提前

+0

thnks @sanbhat为你评论。 – user1979774 2014-09-02 10:03:09

0

按照您的例子抱怨,我能够弄清楚,家长的列表和儿童名单不是彼此的亚型即使子类是Parent的子类型,类似于列表号Integer列表不是任何一个的子类型。如果可能的话,您可以添加一个整数到列表中的数字这导致类型安全脱离。

您的需求,你可以做类似下面的

List<Number> numberList = new ArrayList<Number>(); 

    List<Integer> integerList = new ArrayList<Integer>(); 
    List<Double> doubleList = new ArrayList<Double>(); 
    List<Float> floatList = new ArrayList<Float>(); 

    numberList.addAll(integerList); 
    numberList.addAll(doubleList); 
    numberList.addAll(floatList); 

这里检查参数中的addAll()方法。