了解Java中varargs的意外行为
我在读答案,上面写着 还请注意,使用显式数组参数调用泛型vararg方法可能会产生与预期不同的行为:了解Java中varargs的意外行为,java,Java,我在读答案,上面写着 还请注意,使用显式数组参数调用泛型vararg方法可能会产生与预期不同的行为: public <T> void foo(T... params) { ... } int[] arr = {1, 2, 3}; foo(arr); // passes an int[][] array containing a single int[] element Varargs仅适用于引用类型。自动装箱不适用于基元数组。以下工作: Integer[] myNumbers =
public <T> void foo(T... params) { ... }
int[] arr = {1, 2, 3};
foo(arr); // passes an int[][] array containing a single int[] element
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);
- 请注意,将
传递到intarr
会导致创建单个二维数组tVarargs
和单个元素。但是,此数组的类型是什么[[I
- 此外,将
传递到intarr
会创建包含单个数组元素的一维数组objVarargs()
[Ljava.lang.Object
- 对于rest,它创建了1-D数组,其中包含所传递的元素数——这是所需的行为
有人能更清楚地了解前两种行为吗?这两种行为是不同的行为还是相同的行为,我的意思是它们背后有不同或相同的原因。这些原因是什么?是否有其他情况导致不同的意外行为?这两种行为是由同一问题导致的-泛型类型参数和d
Object
变量只能保存引用类型。原语(如int
)不是引用类型,因此将int
数组传递给varargs方法(不管它是Object…A
还是t…s
)结果该方法接受一个具有单个元素的数组,并且该单个元素是int
数组
因此,您可以将其视为2维<代码> int <代码>数组(即<代码> int [][]/COD>),包含一行。
请注意,tVarargs(T…s)
中有一个打字错误,这会导致输出混乱。它应该是System.out.print(i+“,”);
,而不是System.out.print(s+”,”;
一旦您解决了这个问题,两种方法都会为Integer[]
输入生成相同的输出:
[Ljava.lang.Integer;
3
1,2,3,
int[]
输入输出的差异是因为在objVarargs(Object…a)
中,varargs数组的类型是Object[]
,在tVarargs(T…s)
中是T[]
(当T
是int[]
时,数组的类型是int[]
)
顺便说一句,
[[I
是一个二维int
数组的类名(即int[][]
)。我不知道这里有什么让你困惑。Type…
只是Type[]
但允许我们将类型的参数作为列表传递,而不是手动将其包装到数组中。
仅限于引用类型(它不能表示像int
这样的基元类型),这意味着t...
ast[]
不能是int[]
。如果传递int[]
array然后T
可以使用的最具体的对象类型是数组本身。所以既然T
现在是int[]
T…。
就像int[]…
一样,它导致int[]
(这就是[[I
所代表的)。对象…
就是对象[]
array,这就是您在其他方法中看到的
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,
[Ljava.lang.Integer;
3
1,2,3,