了解 Java 中 varargs 的意外行为
2022-09-04 22:58:12
我正在阅读这个答案,它说
另请注意,使用显式数组参数调用泛型 vararg 方法可能会以静默方式产生与预期不同的行为:
public <T> void foo(T... params) { ... } int[] arr = {1, 2, 3}; foo(arr); // passes an int[][] array containing a single int[] element
类似的行为在这个答案gotcha 3中得到了解释:
int[] myNumbers = { 1, 2, 3 }; System.out.println(ezFormat(myNumbers)); // prints "[ [I@13c5982 ]"
Varargs 仅适用于引用类型。自动装箱不适用于基元数组。以下工作原理:
Integer[] myNumbers = { 1, 2, 3 }; System.out.println(ezFormat(myNumbers)); // prints "[ 1 ][ 2 ][ 3 ]"
我尝试了更简单的例子:
private static <T> void tVarargs(T ... s)
{
System.out.println("\n\ntVarargs ==========");
System.out.println(s.getClass().getName());
System.out.println(s.length);
for(T i : s)
System.out.print(s + ",");
}
private static void objVarargs(Object ... a)
{
System.out.println("\n\nobjVarargs =========== ");
System.out.println(a.getClass().getName());
System.out.println(a.length);
for(Object i : a)
System.out.print(i + ",");
}
int[] intarr = {1,2,3};
Integer[] Intarr = {1,2,3};
objVarargs(intarr);
objVarargs(Intarr);
tVarargs(intarr);
tVarargs(Intarr);
这打印
objVarargs ===========
[Ljava.lang.Object;
1
[I@7852e922,
objVarargs ===========
[Ljava.lang.Integer;
3
1,2,3,
tVarargs ==========
[[I
1
[[I@4e25154f,
tVarargs ==========
[Ljava.lang.Integer;
3
[Ljava.lang.Integer;@70dea4e,[Ljava.lang.Integer;@70dea4e,[Ljava.lang.Integer;@70dea4e,
- 注意传递给结果,创建单个 2 维数组 wit 单个元素。但是,此数组的类型是什么?
intarr
tVarargs
[[I
- 此外,传递给还会导致创建包含单个数组元素的一维数组。
intarr
objVarargs()
[Ljava.lang.Object
- 对于休息,它创建具有与传递的元素一样多的一维数组 - 所需的行为。
有人能对前两种行为有更多的了解吗?这两种不同的行为还是相同的行为,我的意思是它们背后有不同或相同的原因。深入地讲,这些原因是什么?是否有任何其他情况会导致不同的意外行为?