假设我们有两个不同的列表。
List 1可以采用任何Number参数(包括int,double,float和其他所有的Number的子类)。
List<Number> l1 = new ArrayList();
这样做非常合适。
l1.add(123);
l1.add(123.3456);
列表2扩展了Number。问题是我不能添加任何东西,我不明白为什么。另外,为什么我需要一个&lt; ?扩展某事&gt;而不只是创建一个层次结构中最高级别的列表,可以存储任何子类(如列表1)?
List<? extends Number> l2 = new ArrayList();
l2.add(123); //Error, although Integer is a subclass of Number
l2.add(new Integer(123)); // Wrappers don't work either
l2.add(123.456); //Error again
答案 0 :(得分:5)
调用add
方法在具有? extends
通配符的类上具有泛型参数的问题是编译器不知道确切的类型。它可以是List<Number>
或List<Integer>
或List<Double>
或List<BigInteger>
。编译器必须使用泛型保留类型安全性,如果允许这样的调用,则不会保留类型安全性。您不应该被允许将Double
添加到可能是List<Integer>
的列表中。
此类? extends
上限通配符本身可用作方法参数,其中确切类型并不重要;重要的是它的界限(在这种情况下,Number
)或以下。
public void foo(List<? extends Number> list) {
for (Number n : list) {
// do something with some kind of Number, don't care which
答案 1 :(得分:2)
?是编译器未知的通配符。它可以是从数字派生的任何类型的实例。仿制药是为了类型安全的确切目的而实施的,因为进入的类型是未知的,所以这不起作用。
答案 2 :(得分:1)
通配符不能用于修改列表,仅用于处理列表中已包含的元素。如果您创建列表或向列表添加元素,则必须知道列表中确切包含哪些元素。