1

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

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

似乎列表将包含扩展 X 的元素集合。因此,new A()应该符合条件。

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

4

3 回答 3

5

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

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

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

于 2012-08-02T16:09:32.817 回答
2

List<? extends X>没有确定的类型。这意味着list可以从一系列类型中分配变量,例如List<A>, 也可以List<B>(where B extends X)。如果编译器允许您添加new A()到这样的列表,您将添加一个Ato List<B>。那将是类型安全的失败。

于 2012-08-02T16:08:20.333 回答
0

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

于 2012-08-02T16:13:06.430 回答