我知道在列表上使用下界通配符作为方法参数应该让我们放置该下界的元素及其超类型,但考虑以下代码:
public class WildcardError {
void foo(List<? super Number> i) {
i = new ArrayList<Integer>(); //compile error
i.add(new Integer(2)); // no error
}
}
现在在这里我理解了为什么方法foo的第一条语句中会出现编译错误,因为Integer的ArrayList不是“?super Number”的List的子类型,但是为什么我们允许即使在此列表中也将Integer放入此列表中整数不是Number的超类型?也是以下代码中的另一种方式:
public class WildcardError {
void foo(List<? super Integer> i) {
i = new ArrayList<Number>(); //no error
Number k =20;
i.add(k); // compile error
}
}
在这里,我理解语句2中应该没有编译错误,因为Number的ArrayList是“?super Integer”列表的子类型,但是为什么最后一条语句会出现编译错误?
虽然?超级整数应容纳超级类编号。
我试图找到答案,但是找不到确切的情况。
答案 0 :(得分:1)
在第一个示例中,下界? super Number
意味着实际类型参数可以是Number
或超类型(例如Object
)。由于Java的泛型是不变的,因此List<? super Number>
不能与ArrayList<Integer>
匹配。请记住,下限是类型参数的界限,而不是可能作为参数发送的参数类型的界限。对add
的调用没有错误,因为可以将Integer
传递给add
方法,该方法可以使用Number
或超类。
在第二个示例中,下界? super Integer
表示实际类型参数可以是Integer
或超类型(例如Number
,Object
)。这与ArrayList<Number>
相匹配,因此这里没有错误。但是,i
的类型仍然是List<? super Integer>
,不能保证能够采用Number
之类的k
。它可以在任何时候引用List<Integer>
,其中可能是Number
的{{1}}不应被接受。这就是为什么这里会出现编译器错误。