关于java:不兼容的类型ArrayList的List和ArrayList的列表

Incompatible types List of List and ArrayList of ArrayList

下面的一行给出了错误:

1
2
3
Incompatible Types.

List<List<Integer>> output = new ArrayList<ArrayList<Integer>>();

原因是什么?

编辑

我知道如果我把第二个数组列表改成列表,它不会给我带来错误。不过,我想知道出错的原因。谢谢


来自泛型、继承和子类型

This is a common misunderstanding when it comes to programming with
generics, but it is an important concept to learn.

enter image description here

Box is not a subtype of Box even though Integer is a subtype of Number.


如果你有一个List>,那么你就可以添加一个LinkedList。但是你不能为ArrayList>做这个,所以后者不可能是List>的类型。


正确的文字应该是:List> ret = new ArrayList>();因为这样,您不仅可以在ArrayList中添加LinkedList,还可以在ret中添加LinkedList


原因是泛型不是协变的。

考虑更简单的情况:

1
2
3
List<Integer> integers = new ArrayList<Integer>();
List<Number> numbers = integers; // cannot do this
numbers.add(new Float(1337.44));

现在列表中有一个浮动,这肯定是不好的。

你的情况也一样。

1
2
3
List<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>();
List<List<Integer>> ll = al; // cannot do this
ll.add(new LinkedList<Integer>())

现在您有一个包含LinkedListll列表,但是al被声明为ArrayList的列表。


它在Java文档中有明确的表述。

In general, if Foo is a subtype (subclass or subinterface) of Bar, and
G is some generic type declaration, it is not the case that G is
a subtype of G. This is probably the hardest thing you need to
learn about generics, because it goes against our deeply held
intuitions.

同样的事情也发生在这里,它是Bar = ListFoo = ArrayList,因为ArrayList>不是List>的子类型。


更少的文本更多的修复:

1
List<List<Integer>> lists = new ArrayList<>();

1
List<List<Integer>> lists = new ArrayList<List<Integer>>();