是的,T...
仅仅是T[]
的一种语法糖。
列表中的最后一个形式参数是特殊的; 它可以是带有类型后跟省略号的可变元素参数。
如果最后一个形式参数是类型为T
的可变元素参数,则被认为定义了一个类型为T[]
的形式参数。该方法然后是一个可变元素方法。否则,它是一个固定长度方法。调用可变元素方法可以包含比形式参数更多的实际参数表达式。不与变长参数之前的形式参数对应的所有实际参数表达式将被评估,并将结果存储到将传递给方法调用的数组中。
以下是一个例子来说明:
public static String ezFormat(Object... args) {
String format = new String(new char[args.length])
.replace("\0", "[ %s ]");
return String.format(format, args);
}
public static void main(String... args) {
System.out.println(ezFormat("A", "B", "C"));
}
是的,上面的
main
方法是有效的,因为再次提醒,
String...
只是
String[]
。此外,由于数组是协变的,
String[]
是
Object[]
,因此您也可以以任何方式调用
ezFormat(args)
。
另请参阅
Varargs陷阱#1:传递null
如何解析varargs非常复杂,并且有时它会做出可能会让您感到惊讶的事情。
考虑以下示例:
static void count(Object... objs) {
System.out.println(objs.length);
}
count(null, null, null);
count(null, null);
count(null);
由于可变参数的解析方式,最后一个声明将使用
objs = null
调用,这显然会导致
NullPointerException
与
objs.length
。如果你想给可变参数传递一个
null
参数,则可以采取以下任一方法:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
相关问题
以下是一些关于varargs的问题,这是人们在处理varargs时提出的一些问题样例:
Vararg陷阱#2:添加额外参数
正如您所发现的那样,以下操作无法“起作用”:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
由于可变参数的工作方式,实际上 ezFormat 接收到了 2 个参数,第一个是 String[],第二个是 String。如果您将数组传递给可变参数,并且希望其元素被识别为单独的参数,并且还需要添加额外的参数,则只能创建另一个数组来容纳这个额外的元素。
以下是一些有用的辅助方法:
static <T> T[] append(T[] arr, T lastElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
arr[N] = lastElement;
return arr;
}
static <T> T[] prepend(T[] arr, T firstElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
System.arraycopy(arr, 0, arr, 1, N);
arr[0] = firstElement;
return arr;
}
现在你可以做以下事情:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(append(myArgs, "Z")));
// prints "[ A ][ B ][ C ][ Z ]"
System.out.println(ezFormat(prepend(myArgs, "Z")));
// prints "[ Z ][ A ][ B ][ C ]"
Varargs陷阱#3:传递原始类型的数组
它不会“起作用”:
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs只适用于引用类型。自动装箱不适用于原始类型数组。以下是可行的:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"