将元素添加到List <! - ?扩展Superclass - >,需要澄清

时间:2012-08-02 16:02:19

标签: java generics

如果A extends X,以下声明有效

    List<? extends X> list = new ArrayList<A>();

似乎是一个列表会包含一些扩展X的元素集合。因此,new A()应符合条件。

是的,它没有。那是为什么?

3 个答案:

答案 0 :(得分:5)

你几乎得到了它。 List<? extends X>表示“某种类型的列表(我实际上并不知道),它是X的子类型(或者可能是X本身)”。

问题是如果X是,例如Number。然后List<? extends X>表示List<Double>List<Integer>或其他类型,您刚刚说过您实际上并不知道。您无法将任何Number插入List<Integer>。因此,由于您不知道列表元素的类型,因此无法将任何插入List<? extends Number>。但是,您可以从列表中检索值,并确保列表中包含的任何值至少 Number

有关更多信息,请阅读项目28:使用有界通配符来增加Effective Java, 2nd Ed.中的API灵活性,这是Joshua Bloch(每个Java程序员应该在他们的书架上都有的一本书)。特别是,这个项目解释了助记符PECS,意思是“生产者扩展,消费者超级”,它将帮助您记住extendssuper关键字在Java泛型中的含义以及何时应该使用它们。 / p>

答案 1 :(得分:2)

List<? extends X>不是明确的类型。这意味着变量list可以从一系列类型中分配,例如List<A>,还有List<B>(其中B extends X)。如果编译器允许您将new A()添加到此类列表,则会向A添加List<B>。这将是类型安全的失败。

答案 2 :(得分:0)

您正在创建一个通用extends类型的列表引用(变量)。这表明该列表可以包含具有X作为超类的类的实例。但是,在创建列表的实际实例时,您将其限制为仅包含类A的实例。这听起来不奇怪吗?