繁体   English   中英

为什么foo(1,2,3)没有作为整数[]传递给varargs方法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 123Integer (一个或多个),并且由于它们是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... argsObject[] 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适用于VarargsAutoboxing的规则。 编译器生成一个Object数组,因为Object...表示Object[] 因此bar不是Integer[]的实例。 这只是语法糖。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM