为什么List <integer []> listOfArrays = Arrays.asList(new Integer [] {1,2})不能编译?

时间:2016-07-15 13:44:32

标签: java variadic-functions

1)好的

List<int[]> listOfArrays1 = Arrays.asList( new int[]{1, 2} );

2)好的

List<int[]> listOfArrays2 = Arrays.asList( new int[]{1, 2}, new int[]{3, 4} );

3)编译错误Type mismatch: cannot convert from List<Integer> to List<Integer[]>

List<Integer[]> listOfArrays3 = Arrays.asList( new Integer[]{1, 2} );

4)好的

List<Integer[]> listOfArrays4 = Arrays.asList( new Integer[]{1, 2},  new Integer[]{3, 4} );

这是asListpublic static <T> List<T> asList(T... a)

的签名

asList期望0或更多类型为“a”。我的“a”是new Integer[]{1, 2},它的类型为Integer[]。那么,为什么它会生成List<Integer>而不是List<Integer[]>

1 个答案:

答案 0 :(得分:3)

让我们看看问题示例(3rd)

List<Integer[]> listOfArrays3 = Arrays.asList( new Integer[]{1, 2} );

如您所示,方法签名为:

public static <T> List<T> asList(T... a)

在这种特殊情况下,Integer[]正在考虑单T...。可以向T...提供同一对象的数组或未指定数量。由于您指定了一个数组,因此T被视为Integer(而T...变为Integer[]。)

当您提供int[]作为单个参数(1st)时,编译器不会自动将其包装到Integer[],因为这样的对象不同于int[]。由于int不是对象,因此唯一适合T的对象类型是int[](将参数构建为int[][])。

提供两个int[] s (2nd)更加明显,因为编译器只能将T...的两个数组视为int[] s,因此{ {1}}也是T...

当您提供两个int[][] s (第四个)时,再次更明显的是编译器别无选择,只能将构成Integer[]的两个参数视为T...(成为单个数组:Integer[])。

编辑:将数组作为vararg提供:

可以提供单个数组作为vararg。让我们举一个没有通用的例子:

Integer[][]

public int iLoveMeSomeInts(int...nums) 作为参数提供给此方法确实有效。为验证签名,数组被视为int[]的变量,然后vararg被视为方法内部逻辑的int

您的示例中的差异是参数为int[]。通用T... 必须是一个对象,因此在这种情况下,编译器不能将T视为int[]的变量。然后,编译器别无选择,只能将int...视为int[]的vararg中的单个元素(因为int[]...是一个对象)。这没有任何含糊之处。

但是,由于int[] 对象,编译器将使用单个Integer作为Integer[]

更酷的是:如果您希望使用相关方法返回Integer...,并且仍然只提供一个Integer[],则可以致电:

Integer[]

这会强制编译器将您的单个Arrays.<Integer[]>asList(new Integer[] {1, 2}); 视为Integer[]