使用 (int...i) 和 (Integer...i) 的 varagrs 有什么区别

What is difference between varagrs using (int...i) and (Integer...i)

当我 运行 这段代码有两个不同的可变参数 (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
test(null);
    Integer... 时,
  • null 可能是 IntegerInteger
  • 时,
  • null 可能是 Integer[]
  • null 不能是 int 值,当 int...
  • int 时,
  • null 必须是 int[]

要记住的一件关键事情是可变参数被编译为创建和接受数组。也就是说,

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[] 参数是完全可接受的,因此调用编译时没有警告。

区别在于null在两种方法中的解释方式。

第一种方法 public static void test(Integer...i) 需要 Integer 类型的参数列表或其数组 Integer[]。因此,如果您传递 test(null); 编译器会感到困惑,因为 null 可以是两种类型。这意味着您可以传递 IntegerInteger[]。需要显式转换。

在第二种情况下 public static void test(int...i) 需要 int 类型的参数,它是一个 原始类型 类型或其数组, int[] 这将是一个引用类型。由于原始类型不能是 null,编译器知道您将 null 作为 int[] 传递,因此不会给您警告。