我宣布收集
List<? extends Number> ml = new Vector<Integer>();
我尝试添加元素
无效:
ml.add(new Integer(1));
它太
了ml.add(new Object());
我非常困惑。我如何使用ml
?
答案 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成为只读列表。这就是为什么你不能在其中添加任何元素,只需获取并阅读它们。 将其更改为:列表