2013-04-12 51 views
4

不工作,我有以下代码:代码与超级仿制药有望

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 

,这是什么原因呢?

回答

9

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

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

numbers.add(new Object())不工作的原因是,你只允许Object s添加到List<Object> S,但numbers很可能是一个List<Integer>List<Number>(事实上是后者),所以这是不允许。

基本上你想它是这样的:numbers可能是Integer个清单,Number的List或Object个列表,所以你只允许执行那些将工作在任行动其中之一。

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 
1

通过声明List<? super Integer>,您是说它可以接受超类Integer的任何对象,其中也包括NumberObject。因此,您可以在列表中添加NumberObject的实例,以便从列表中检索最常用的类型,即Object

-1

我认为你正在寻找加载列表与任何超级整数。对象是整数超级的唯一类。

编号是一个对象,因此编写new ArrayList<Number>()是合法的;

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

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

问候, Venod

+2

这是不对的,'Number' *为* Integer'的'超类。 – sepp2k

+0

我认为他不认为'Number'是'抽象类';) – NINCOMPOOP

+0

@noob你太善良了。 – cowls