使用super的泛型代码无法按预期工作

时间:2013-04-12 15:44:03

标签: java generics compiler-construction type-conversion

我有以下代码:

List<? super Integer> numbers = new ArrayList<Number>();
numbers.add(new Integer(10));
Number object = numbers.get(0);  //this doesn't compile??

Object object = numbers.get(0);  //this does compile

然后,如果我这样做:

numbers.add(new Object()); //doesn't compile in contradiction to above statement

这是什么原因?

4 个答案:

答案 0 :(得分:9)

Number object不起作用,因为编译器不知道numbersNumber的列表 - 它只知道它是一个超类{的列表{1}}。例如,它可能是Integer的列表,在这种情况下,将Object的结果存储在get变量中将不起作用。因此编译器不允许它。

允许

Number,因为将Object object的结果存储在get变量中始终有效,因为您可以将任何内容存储在Object变量中。

Object不起作用的原因是,您只能将numbers.add( new Object() )添加到Object,但List<Object>很可能是numbers {1}}或List<Integer>(事实上它是后者),所以不允许这样做。

基本上你必须这样想:List<Number>可能是numbers列表,Integer列表或Number列表,所以你只能被允许执行那些可以对这三个中的任何一个起作用的动作。

答案 1 :(得分:4)

List<? super Integer>允许numbers成为Objects的列表,而不仅仅是Numbers列表或Integers列表:

List<? super Integer> numbers = new ArrayList<Object>();

完全基于numbers的编译时类型,不能保证以下类型安全,因此被拒绝:

Number object = numbers.get(0);  //this doesn't compile

答案 2 :(得分:1)

通过声明List<? super Integer>,您说它可以接受任何包含IntegerNumber的{​​{1}}超类的对象。因此,您可以在该列表中添加ObjectNumber的实例,以便在从列表中检索时考虑最通用的类​​型,即Object

答案 3 :(得分:-1)

我认为您希望使用任何超级整数类加载List。 Object是Super of Integer的唯一类。

Number是一个Object,因此编写new ArrayList<Number>();

是合法的

但是当你试图从numbersList获取时,它只能是一个Object。 因为Object是唯一的Integer超级类。

如果您有任何疑问,或者您认为我需要纠正我的理解,请告诉我。

此致 Venod