带有 super 的泛型代码无法按预期工作

问题描述 投票:0回答: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

这是什么原因?

java generics
4个回答
9
投票

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

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

numbers.add( new Object() )
不起作用的原因是你只能将
Object
添加到
List<Object>
,但
numbers
很可能是
List<Integer>
List<Number>
(并且在事实上是后者),所以这是不允许的。

基本上你必须这样想:

numbers
可能是
Integer
的列表、
Number
的列表或
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
超类的对象,其中还包括
Number
Object
。因此,您可以在该列表中添加
Number
Object
的实例,以便在从列表中检索最通用的类型时,即
Object
被视为。


-1
投票

我认为您正在寻找使用任何超级整数类加载列表。 Object是唯一一个Super of Integer的类。

Number 是一个对象,因此写

new ArrayList<Number>()
;

是合法的

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

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

问候, 维诺

© www.soinside.com 2019 - 2024. All rights reserved.