嵌套有界通配符 [英] Nested Bounded Wildcard
问题描述
当我尝试编译以下代码时:
LinkedList< List <?扩展Number>> numList = new LinkedList< List< Integer>>();
我得到一个不兼容的类型错误:
必需:LinkedList< java.util.list< extends java.lang.Number>>
Found:LinkedList< java.util.list< Integer>>
如何获得 LinkedList
包含元素 List
s元素扩展数字
?
为了说清楚,我正在寻找以下列方式将列表添加到 numList
中:
numList.add(new LinkedList< Integer>());
通配符捕获不会超过一个通用级别。因此,虽然这工作:
LinkedList <?扩展Number> test = new LinkedList< Integer>();
这不会:
链表<名单,LT ;?扩展Number>> numList = new LinkedList< List< Integer>>();
我能想到的最合理的解释是将泛型看作最外层的不变量。 A LinkedList< List< Integer>>
不是 LinkedList< List<即使
是 List< ;?扩展Number>>
由于与 List< Dog>
不是 List< Animal> $相同的原因,扩展Number>
c $ c>即使 Dog
是 Animal
。在这里, Dog
是 List< Integer>
是列表<?扩展数字>
。
那么,Dog / Animal解决方案是?
:
列表< ;?延伸动物> animals = new List< Dog>();
应用相同的推理,解决方法是另一个?扩展
:
LinkedList <?扩展List <?扩展Number>> numList = new LinkedList< List< Integer>>();
但是,您将无法向此列表添加任何内容,因为第一个?延伸
。引用类型变量 numList
不知道 List <>的哪个子类型?扩展Number>
它确实是;它可以是 ArrayList< Integer>
,所以Java不能提供类型安全性,以至于可以将这样的东西添加到这样的 LinkedList
。为了保持类型安全,编译器只允许添加 null
。您必须完全匹配泛型类型参数,而不使用通配符: LinkedList< List< Integer>> numList = new LinkedList< List< Integer>>();
。您可以为 LinkedList
添加 List< Integer>
。
When I try to compile the following code:
LinkedList<List<? extends Number>> numList = new LinkedList<List<Integer>>();
I get an incompatible type error:
Required: LinkedList <java.util.list<? extends java.lang.Number>>
Found: LinkedList <java.util.list<Integer>>
How can I achieve having a LinkedList
which contains elements that are List
s with elements that extend Number
?
To be clear, I'm looking to add lists to numList
in the following fashion:
numList.add(new LinkedList<Integer>());
Wildcard capture does not go more than one generic level deep. So while this works:
LinkedList<? extends Number> test = new LinkedList<Integer>();
This does not:
LinkedList<List<? extends Number>> numList = new LinkedList<List<Integer>>();
The most reasonable explanation I can think of is to think of generics as invariant at the outermost level. A LinkedList<List<Integer>>
is not a LinkedList<List<? extends Number>>
, even though a List<Integer>
is a List<? extends Number>
, for the same reason that a List<Dog>
is not a List<Animal>
even though a Dog
is an Animal
. Here, Dog
is to Animal
as List<Integer>
is to List<? extends Number>
.
Well, the Dog/Animal solution is ? extends
:
List<? extends Animal> animals = new List<Dog>();
Applying the same reasoning, the workaround is another ? extends
:
LinkedList<? extends List<? extends Number>> numList = new LinkedList<List<Integer>>();
However, you won't be able to add anything to this list because of the first ? extends
. The reference type variable numList
doesn't know which subtype of List<? extends Number>
it really is; it could be ArrayList<Integer>
, so Java cannot provide the type safety that such a thing can be added to such a LinkedList
. To maintain type safety, the compiler will only allow adding null
. You'll have to match the generic type parameters exactly, with no wildcards: LinkedList<List<Integer>> numList = new LinkedList<List<Integer>>();
. You can add a List<Integer>
to such a LinkedList
.
这篇关于嵌套有界通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!