如何创建ArrayLists的ArrayList,使其符合程序到接口原则

时间:2014-09-22 03:43:06

标签: java list arraylist

我知道这个问题已经被解决了,但我从不同的角度看待它。 提供了generic type for ArrayList of ArrayLists的答案。但是,我正在寻找最佳实践和编程接口。然后我想出了以下三个选项。

问题:

  1. 为什么选项1是编译错误?为什么不能进行转换?

  2. 首选哪个选项2或3哪个?

  3. 在选项3中为什么界面" List"出现在声明的右边?请提供适当的答案。我需要了解这些嵌套的通用定义。

     1) List<List<Integer>> arList1 = new ArrayList<ArrayList<Integer>>();
     2) List<ArrayList<Integer>> arList2 = new ArrayList<ArrayList<Integer>>();
     3) List<List<Integer>> arList3 = new ArrayList<List<Integer>>();
    

2 个答案:

答案 0 :(得分:2)

  1. 此代码:

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

    是编译错误,因为List<List<Integer>>可以合法地保留LinkedList<Integer>,但分配的右侧不能。泛型不是协变的。 (见优秀的article on generics by Brian Goetz。)

  2. 除非我明确要求添加到arList2的列表必须是ArrayList的实例,否则我更喜欢3。虽然这种要求很少见,但可能会出现。

  3. 在Java 7中,您不需要这样做。你可以写:

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

    并且编译器将填充List<Integer>作为右侧的泛型类型参数。对于Java 6及更早版本,您需要为构造函数调用显式提供一个泛型参数,该参数与赋值左侧的泛型参数兼容。

答案 1 :(得分:0)

选项1是编译错误,因为类型不兼容。实际上,您可以将List ArrayList放入List<List<Integer>>,但不能放入ArrayList<ArrayList<Integer>>。这就是List出现在选项3右侧的原因。

选项3是首选,因为它通过接口引用对象。参见Joshua Bloch, Effective Java:Programming Language Guide ,item 34。