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} );
这是asList
:public static <T> List<T> asList(T... a)
asList
期望0或更多类型为“a”。我的“a”是new Integer[]{1, 2}
,它的类型为Integer[]
。那么,为什么它会生成List<Integer>
而不是List<Integer[]>
?
答案 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[]
。