为什么不能在上限generics列表中添加元素?
我有一个上限generics的列表。
List l = new ArrayList(); l.add(new Integer(3)); //ERROR l.add(new Double(3.3)); // ERROR
我不明白这个问题,因为Integer和Double扩展了Number。
List extends Number>
List extends Number>
并不意味着“一个可以容纳Number
的子类的所有对象的列表”,它意味着“一个参数化为一个扩展Number
具体类的列表”。 它不是你定义的列表本身的内容,它是分配给变量的实际列表对象的参数化类型可以是什么(男孩,这比理解它更难解释:))
所以,你可以这样做:
List extends Number> l = new ArrayList(); List extends Number> l = new ArrayList();
如果您想要一个能够容纳类Number或其子类的任何对象的列表,请执行以下操作:
List l = new ArrayList<>(); l.add(new Integer(33)); l.add(new Double(33.3d));
(插入的值的装箱是不成功的,但是那个例子..)
上限和无界通配符集合是不可变的。
例如,你做不到:
List extends Number> myList = new ArrayList(); myList.add(new Integer(3)); //will not compile
这无法编译,因为java不知道什么类型的List List extends Number>
List extends Number>
在编译时。
所以上面的例子,在编译时, myList
可以是List
或List
或Number
的任何子类的List
。 由于您无法将Double
添加到List
或反之亦然,因此编译失败。
我将添加一种方法来将Number
的子类型添加到此列表中。 即
List super Number> l = new ArrayList<>(); l.add(new Integer(3)); //OK l.add(new Double(3.3)); //OK
这是允许的,因为列表被参数化为 Number
类的任何未知超类型 。 所以,编译器允许已知的Number
子类型。 即Integer
和Double
类型
因为List extends Number>
List extends Number>
表示您的变量l
包含List
类型的值,具有扩展Number
具体 (但未知!)类型参数。
您只能添加null
,因为l
可以包含List
,其中MyClass
是扩展Number
的类,但也不是Integer
,也不能将Double
值转换为MyClass
。
是的,如果是的话
List extends Number>
这只是一个参考,可能是实际的对象
List
所以不应该允许在Integer列表中添加新的Double(5.0)。