![](/img/trans.png)
[英]Why is it not allowed in Java to overload Foo(Object…) with Foo(Object[])?
[英]Why is foo(1,2,3) not passed to varargs method foo(Object… ) as an Integer[]
请考虑以下代码行:
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)
的情况下,术语bar instanceof Integer[]
为假。
如果在这些情况下bar不是Integer[]
的实例,那还有什么实例呢?
foo(1,2,3);
这一个autoboxes 1
, 2
和3
到Integer
(一个或多个),并且由于它们是Object
的子类型,一个Object[]
被创建的数组,由三个Integer
秒。 数组Object[]
不是Integer[]
,这就是你false
的原因。
foo(new Integer(1), new Integer(2), new Integer(3));
在这里,不应用自动装箱,但最后你将再次拥有一个由三个Integer
组成的数组Object[]
。 同样, Object[]
不是Integer[]
,这就是你false
的原因。
foo(new Integer[]{1,2,3});
在这里,您只有一个参数,与前两个案例不同,您将三个参数包装在一个数组中。 因此,只有一个参数Integer[]
,在运行时,比较bar instanceof Integer[]
将返回true
,因为整数是你实际拥有的。
foo(new Integer[] {new Integer(1), new Integer(2), new Integer(3)});
与前一个相同 - 在运行时,您将检查提供的数组Integer[]
是否为Integer
的数组,这是true
。
根据Java语言规范 :
如果RelationalExpression的值不为null并且引用可以在不引发ClassCastException的情况下将引用(第15.16节)转换为ReferenceType,则instanceof运算符的结果为true。
在您的情况下, Object[]
参数不能转换为Integer[]
因此它返回false。
bar不是整数数组的情况是因为它是你在foo
方法签名中指定的Object数组: Object... args
是Object[] args
语法糖,当解析为此方法时,编译器将创建一个Object数组。
为了始终拥有一个Integer数组,您可以将foo
方法签名更改为foo(Integer... args)
Varargs只是用于创建和传递数组的语法糖。 由于您将方法定义为
public static void foo(Object... bar)
如果将方法调用为foo(1,2,3)
或foo(new Integer(1), new Integer(2), new Integer(3))
Java会为您创建一个Object[]
数组。
但是,您也可以将自己的数组传递给需要varargs参数的方法。 在这种情况下,Java不会为您创建新数组,它只是传递您创建的数组。 在最后两次调用中,您显式创建了一个Integer[]
数组。
在调用foo(1,2,3);
的情况下foo(1,2,3);
编译器(在本例中为javac
)生成代码foo(new Object[]{new Integer(1), new Integer(2), new Integer(3)})
。
javac
适用于Varargs和Autoboxing的规则。 编译器生成一个Object
数组,因为Object...
表示Object[]
。 因此bar
不是Integer[]
的实例。 这只是语法糖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.