当我使用两个不同的varargs(Integer ... i)和(int ... i)运行此代码时,带有(Integer ... i)的代码输出显示警告消息,另一个正确运行。但我无法理解它们之间的差异。
public static void test(Integer...i) {
System.out.println("int array");
}
public static void main(String[] args) {
test(null);
}
运行此代码时,会显示警告消息。
File.java:11: warning: non-varargs call of varargs method with inexact argument type for last parameter;
test(null);
^cast to Integer for a varargs call
但是当我将varargs(Integer ... i)更改为(int ... i)时,代码运行得非常完美。
public static void test(int...i) {
System.out.println("int array");
}
public static void main(String[] args) {
test(null);
}
输出显示为:
int array
答案 0 :(得分:7)
要记住的一件重要事情是varargs被编译为创建和接受数组。也就是说,
void test(Integer... i)
和
void test(Integer[] i)
实际上是一回事。 (挥手。有一些簿记差异。)当你打电话时:
test(i1, i2, i3);
......电话真的是
test(new Integer[] { i1, i2, i3 });
这就是问题的根源。
使用Integer...
,当您使用test(null)
时,您表示要将null
作为可能是多个的第一个整数,因为Integer
是一种引用类型,因此null
可以匹配它。因此,您为数组中的第一个条目传递了一个不精确的类型,例如test(new Integer[] { null })
。
使用int...
,当您使用test(null)
时,null
无法成为第一个int
,因为int
不是引用类型。因此编译器确定您将null
作为数组本身传递。您无法尝试test(new int[] { null })
,因为这样做无效;所以你必须做test((int[])null)
。由于null
完全可以接受int[]
参数,因此调用会在没有警告的情况下进行编译。
答案 1 :(得分:0)
test(null);
null
时,Integer
可能是Integer...
当null
Integer[]
可能是Integer
{li> null
在int...
null
时,int[]
必须是int
答案 2 :(得分:0)
区别在于两种方法中null
的解释方式。
第一种方法public static void test(Integer...i)
需要Integer
类型的参数列表或其数组Integer[]
。因此,如果传递test(null);
,编译器会感到困惑,因为null
可以是两种类型。这意味着您可以传递Integer
或Integer[]
。需要明确的演员表。
在第二种情况下,public static void test(int...i)
需要类型int
的参数,它是原语类型或其数组,int[]
是参考类型。由于原始类型不能是null
,编译器会理解您将null
作为int[]
传递,因此不会给出警告。