1

为什么我不能像这样声明列表列表?

List<List<Object>> a = new ArrayList<ArrayList<Object>>();

ArrayList 是 List 类型,所以我认为上面的代码是有效的。

这是有效的:

List<ArrayList<Object>> b = new ArrayList<ArrayList<Object>>();

内部列表必须声明为 ArrayList。

有人可以解释一下吗?

4

2 回答 2

2

你混淆了你的泛型。做你想做的事的方法是

List<List<Object>> a = new ArrayList<List<Object>>();

通过ArrayList在泛型参数内使用,您将对象的范围从Listto缩小ArrayList,从而更改泛型签名。通过ArrayList在泛型之外使用,您仍然符合要求;您正在指定List要使用的实现,并且它将包含的对象是 type List<Object>,与左侧状态完全相同。

要了解为什么这很重要,请考虑以下列表:

// Invalid declaration, but pretend it is valid
List<List<Object>> a = new ArrayList<ArrayList<Object>>();
a.add(new ArrayList<Object>()); // valid
a.add(new LinkedList<Object>()); // not valid because it's not an ArrayList; 
                                 // but according to the left side, it is valid!

当然,最好的方法是使用 Java 7 的菱形运算符

List<List<Object>> a = new ArrayList<>();
于 2013-09-20T03:13:29.933 回答
1

这不是内部列表的问题,而是泛型参数的问题。只要泛型参数相同(即ArrayList<Object>),初始化就会成功。否则,Java 不允许您进行赋值,因为编译器无法保证类型安全。

想象一下这是可能的:

// Let's pretend this compiles:
List<List<Object>> a = new ArrayList<ArrayList<Object>>();

现在以下必须有效:

a.add(new LinkedList<Object>());

但是,这是无效的,因为对象是一个ArrayListof ArrayLists,所以往里面插入一个链表显然是无效的。

但是,您可以这样做:

List<List<Object>> a = new ArrayList<List<Object>>();

这应该足以对接口进行编程。

于 2013-09-20T03:15:01.683 回答