为什么 foo(1,2,3) 没有作为 Integer 传递给 varargs 方法 foo(Object... )

2022-09-02 20:13:13

请注意以下代码行:

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[]


答案 1
  • foo(1,2,3);

这一个 autobox 和 to (s),并且由于它们是子类型,因此将创建一个由三个 s 组成的数组。数组不是,这就是为什么你得到.123IntegerObjectObject[]IntegerObject[]Integer[]false


  • foo(new Integer(1), new Integer(2), new Integer(3));

在这里,没有自动装箱适用,但最终您将再次拥有一个由三个s组成的数组。同样,不是,这就是为什么你得到.Object[]IntegerObject[]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)});

与上一个相同 - 在运行时,您将检查提供的数组是否是s的数组,即。Integer[]Integertrue


答案 2

根据 Java 语言规范

如果 RelationalExpression 的值不为 null,并且可以将引用强制转换为 ReferenceType 而不引发 ClassCastException,则 instanceof 运算符的结果为 true。

在您的情况下,该参数不能转换为 ,因此它返回 false。Object[]Integer[]