【发布时间】:2018-11-13 13:07:22
【问题描述】:
我正在阅读this 的答案,上面写着
另请注意,使用显式数组参数调用泛型可变参数方法可能会默默地产生与预期不同的行为:
public <T> void foo(T... params) { ... } int[] arr = {1, 2, 3}; foo(arr); // passes an int[][] array containing a single int[] element
this answer gotcha 3 中解释了类似的行为:
int[] myNumbers = { 1, 2, 3 }; System.out.println(ezFormat(myNumbers)); // prints "[ [I@13c5982 ]"可变参数仅适用于引用类型。自动装箱不适用于基元数组。以下作品:
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,
- 将
intarr传递给tVarargs的通知会导致创建单个二维数组[[I和单个元素。但是,这个数组的类型是什么? - 此外,将
intarr传递给objVarargs()会导致创建一维数组[Ljava.lang.Object,其中包含单个数组元素。 - 对于其余部分,它会创建一维数组,其中包含与传递一样多的元素 - 所需的行为。
有人可以更深入地了解前两种行为吗?这是两种不同的行为还是相同的行为,我的意思是它们背后有不同或相同的原因。这些原因是什么?是否还有其他情况导致不同的意外行为?
【问题讨论】:
-
我不知道是什么让你感到困惑。
Type...只是Type[]但允许我们将Type的参数作为列表传递,而不是手动将其包装到数组中。<T>仅限于引用类型(它不能表示像int这样的原始类型),这意味着T...因为T[]不能是int[]。如果您传递int[]数组,那么T可以使用的最具体的对象类型就是数组本身。所以因为T现在是int[]T...就像int[]...导致int[][](这就是[[I所代表的)。Object...只是Object[]数组,这就是您在其他方法中看到的
标签: java