当我尝试编译以下代码时:
LinkedList<List<? extends Number>> numList = new LinkedList<List<Integer>>();
我收到了一个不兼容的类型错误:
Required: LinkedList <java.util.list<? extends java.lang.Number>>
Found: LinkedList <java.util.list<Integer>>
如何让LinkedList
包含List
个包含Number
元素的元素?
要清楚,我希望以下列方式向numList
添加列表:
numList.add(new LinkedList<Integer>());
答案 0 :(得分:14)
通配符捕获不会超过一个通用级别。所以虽然这有效:
LinkedList<? extends Number> test = new LinkedList<Integer>();
这不是:
LinkedList<List<? extends Number>> numList = new LinkedList<List<Integer>>();
我能想到的最合理的解释是将泛型视为最外层的不变量。 LinkedList<List<Integer>>
不是LinkedList<List<? extends Number>>
,即使List<Integer>
是List<? extends Number>
,原因与List<Dog>
不是List<Animal>
的原因相同即使Dog
是Animal
。此处Dog
为Animal
,List<Integer>
为List<? extends Number>
。
好吧,狗/动物解决方案是? extends
:
List<? extends Animal> animals = new List<Dog>();
应用相同的推理,解决方法是另一个? extends
:
LinkedList<? extends List<? extends Number>> numList = new LinkedList<List<Integer>>();
但是,由于第一个? extends
,您将无法向此列表添加任何内容。引用类型变量numList
不知道它实际上是List<? extends Number>
的哪个子类型;它可能是ArrayList<Integer>
,因此Java无法提供类型安全性,可以将此类内容添加到此类LinkedList
中。为了保持类型安全,编译器只允许添加null
。您必须准确匹配泛型类型参数,不使用通配符:LinkedList<List<Integer>> numList = new LinkedList<List<Integer>>();
。您可以将List<Integer>
添加到此类LinkedList
。