Ray*_*oal 8 java arrays generics variadic-functions
如果我写Java方法
public static void f(int... x) {
for (int a: x) {
System.out.println(a);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以通过调用此方法
f(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
以及
f(new int[]{1, 2, 3});
Run Code Online (Sandbox Code Playgroud)
并且两个电话的处理方式完全相同.但是,这两个电话
Arrays.asList(1, 2, 3) // (a) produces a three-element Integer list
Run Code Online (Sandbox Code Playgroud)
和
Arrays.asList(new int[]{1, 2, 3}) // (b) produces a one-element list of Integer arrays
Run Code Online (Sandbox Code Playgroud)
不一样对待. 关于在JLS中评估参数的部分说明" m的最终形式参数必然具有T[]某些类型T",那么为什么不是上面情况(b)中的"最终形式参数" 不是一个可以创建三元素的整数数组列表,如案例(a)?
我唯一能想到的是Arrays.asList通用的,关于类型兼容性的东西(在JLS第15.12.4.2节中提到)在这里起作用,但是我不能完全理解JLS中的实际句子两种情况不同.
JLS中的评论谈到了为了处理"参数化类型和Java虚拟机中发生的带有擦除泛型的数组类型"之间的相互作用,需要仔细制作这些语义,但我们最终得到的是我的功能f并且Arrays.asList似乎表现得很好不一致.在前一种情况下,我可以"解包"或"打包"我的args,一切都是一样的; 在后一种情况下,这两种情况是不同的.
这是如何用语言律师的术语解释的?
Arrays.asList被定义为具有参数T...,并且正文将其视为类型的一个参数T[].但是,T 必须是引用类型(与任何类型参数一样),并且int不是引用类型.因此,没有办法new int[]{...}与varargs目的的数组兼容.(并且结果将List<int>是不允许的.)唯一的选择是将其视为单个对象,因此T这将int[]是一个引用类型,函数将返回一个List<int[]>.
我认为这就是原因,尽管我仍然需要查找确切的语言.它可能涉及类型推断规则,我还没有掌握.
但是,我确实试过这个:
List x = Arrays.asList(new int[]{1, 2, 3});
List y = Arrays.asList(new Integer[]{1, 2, 3});
System.out.println(x.size());
System.out.println(y.size());
Run Code Online (Sandbox Code Playgroud)
(请注意,我故意使用List原始类型,我在实际代码中不会这样做).输出:
1
3
Run Code Online (Sandbox Code Playgroud)