我可以用这个List <! - 相同的泛型做什么? ...-->?

时间:2014-03-03 20:26:46

标签: java generics collections type-conversion covariance

我宣布收集

 List<? extends Number> ml = new Vector<Integer>();

我尝试添加元素

无效:

ml.add(new Integer(1));

它太

ml.add(new Object());
我非常困惑。我如何使用ml

3 个答案:

答案 0 :(得分:4)

列表不协变。如果您使用? extends Number,那么您只能从列表中读取,您无法写入。为什么不呢?

m1.add(new Object());

显然为什么这不起作用。该列表应包含Number个,而Object不是Number

ml.add(new Integer(1));

这个不是那么明显。想象一下,您有m1的不同实例:

List<? extends Number> ml = new Vector<Double>();
ml.add(new Integer(1));

现在m1是双打的向量。在此列表中添加整数将是非法的。编译器通常不知道? extends Number的具体类型是什么。保守一点,它不允许完全调用add方法。您可以遍历列表并阅读其中的内容,并且可以从中删除项目,但不能向其中添加新项目。

或者换句话说,对于List<E>,您可以调用返回E的方法,但不能将那些以E作为参数的方法调用。

答案 1 :(得分:2)

您无法调用使用上限通配符参数化的方法。除了捕获通配符本身之外,任何类型都不能满足该通配符。

list.add(E e)

结束为

list.add(<capture-of ? extends Number> e)

变量ml的类型没有捕获。

答案 2 :(得分:1)

在这里,您将ml声明为通用列表。由于您使用的是通配符,因此您只能知道所包含对象的实际类型可能是数字或其中一个子类型。但是JVM并不真正知道这种类型到底是什么。因此,此声明使ml成为只读列表。这就是为什么你不能在其中添加任何元素,只需获取并阅读它们。 将其更改为:列表