Java 为什么foo(1,2,3)没有作为整数[]传递给varargs方法foo(Object…)
请注意以下代码行:Java 为什么foo(1,2,3)没有作为整数[]传递给varargs方法foo(Object…),java,variadic-functions,autoboxing,Java,Variadic Functions,Autoboxing,请注意以下代码行: public static void main(String[] args) { foo(1,2,3); System.out.println("-------------------------------------"); foo(new Integer(1), new Integer(2), new Integer(3)); System.out.println("------------------------------------
public static void main(String[] args) {
foo(1,2,3);
System.out.println("-------------------------------------");
foo(new Integer(1), new Integer(2), new Integer(3));
System.out.println("-------------------------------------");
foo(new Integer[]{1,2,3});
System.out.println("-------------------------------------");
foo(new Integer[] {new Integer(1), new Integer(2), new Integer(3)});
}
public static void foo(Object... bar) {
System.out.println("bar instanceof Integer[]:\t" + (bar instanceof Integer[]));
System.out.println("bar[0] instanceof Integer:\t" + (bar[0] instanceof Integer));
System.out.println("bar.getClass().isArray():\t" + bar.getClass().isArray());
}
此代码段的输出为:
bar instanceof Integer[]: false
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: false
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: true
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: true
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
这让我很困惑!我不明白为什么在foo(1,2,3)
的情况下,Integer[]的术语bar instanceof为false
如果在这些情况下,bar不是Integer[]
的实例,那么它是什么的实例?bar不是整数数组的情况是因为它是您在foo
方法签名中指定的对象数组:对象。。。args
是对象[]args
的语法糖,当解析为该方法时,编译器将创建一个对象数组
为了始终拥有整数数组,您可以将foo
方法签名更改为foo(Integer…args)
foo(1,2,3)代码>
这一个将1
、2
和3
自动装箱到Integer
(s),由于它们是Object
子类型,因此创建了一个Object[]
数组,由三个Integer
组成。数组对象[]
不是整数[]
,这就是为什么会得到false
foo(新整数(1)、新整数(2)、新整数(3))代码>
在这里,不应用自动装箱,但最终您将再次拥有一个由三个整数组成的数组对象[]
。同样,Object[]
不是Integer[]
,这就是为什么会得到false
foo(新整数[]{1,2,3})代码>
这里只有一个参数,与前两种情况不同,在前两种情况下,将三个参数包装到一个数组中。因此,只有一个参数Integer[]
,在运行时,Integer[]
的比较条实例将返回true
,因为整数是您实际拥有的
foo(新整数[]{新整数(1)、新整数(2)、新整数(3)})代码>
与前一个相同-在运行时,您将检查所提供的数组Integer[]
是否是Integer
s的数组,在调用foo(1,2,3)的情况下,这是true
代码>编译器(在本例中为javac
)生成代码foo(新对象[]{newinteger(1)、newinteger(2)、newinteger(3)})
javac
应用和的规则。编译器生成一个Object
数组,因为Object…
表示Object[]
。因此,bar
不是Integer[]
的实例。它只是语法上的糖。根据:
如果RelationalExpression的值不为null,并且引用可以转换为ReferenceType(§15.16),而不引发ClassCastException,则instanceof运算符的结果为true
在您的例子中,对象[]
参数不能强制转换为整数[]
,因此它返回false。Varargs只是创建和传递数组的语法糖。因为您将方法定义为
public static void foo(Object... bar)
如果将方法调用为foo(1,2,3)
或foo(新整数(1)、新整数(2)、新整数(3)),Java将为您创建一个Object[]
数组
但是,您也可以将自己的数组传递给需要varargs参数的方法。在这种情况下,Java不会为您创建新的数组,它只是传递您创建的数组。在最后两个调用中,您显式创建了一个整数[]
数组。我认为第一个和第二个应该是对象数组,而不是整数数组。例如,您可以将字符串传递给varargs,它最初应该是对象[]
,而不是整数[]
。对于最后两个问题,您将明确地传递一个整数[]
,因此您的条件现在将为真。这是一个有趣的问题!一个建议:尝试添加foo(newint[]{1,2,3})的测试代码>。结果将从混乱变为怪异@Lii oh well:D将int[]
解释为单个对象,而不是包装所有int
s!很好的补充!啊,好吧,我想我现在明白我的错误了。我(错误地)假设一个只包含整数的对象[]
将是一个整数[]
(仔细想想,这当然是错误的!)谢谢!对演员们说:这就是我第一次遇到这个问题的原因;)