Sí, a T...
es solo un azúcar sintáctico para a T[]
.
El último parámetro formal en una lista es especial; puede ser un parámetro de aridad variable , indicado por una elipsis que sigue al tipo.
Si el último parámetro formal es un parámetro de tipo variable de aridad T
, se considera que define un parámetro formal de tipo T[]
. El método es entonces un método de aridad variable . De lo contrario, es un método de arity fijo . Las invocaciones de un método de aridad variable pueden contener más expresiones de argumentos reales que parámetros formales. Se evaluarán todas las expresiones de argumentos reales que no corresponden a los parámetros formales que preceden al parámetro de aridad variable y los resultados se almacenan en una matriz que se pasará a la invocación del método.
Aquí hay un ejemplo para ilustrar:
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"));
// prints "[ A ][ B ][ C ]"
}
Y sí, el main
método anterior es válido, porque de nuevo, String...
es justo String[]
. Además, debido a que las matrices son covariantes, a String[]
es an Object[]
, por lo que también puede llamar de ezFormat(args)
cualquier manera.
Ver también
Varargs gotchas # 1: pasando null
Cómo se resuelven los varargs es bastante complicado, y a veces hace cosas que pueden sorprenderlo.
Considere este ejemplo:
static void count(Object... objs) {
System.out.println(objs.length);
}
count(null, null, null); // prints "3"
count(null, null); // prints "2"
count(null); // throws java.lang.NullPointerException!!!
Debido a cómo se resuelven los varargs, la última instrucción invoca con objs = null
, lo que por supuesto causaría NullPointerException
con objs.length
. Si desea dar un null
argumento a un parámetro varargs, puede hacer lo siguiente:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Preguntas relacionadas
La siguiente es una muestra de algunas de las preguntas que las personas han formulado al tratar con varargs:
Vararg gotchas # 2: agregar argumentos adicionales
Como descubrió, lo siguiente no "funciona":
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Debido a la forma en que funcionan los varargs, en ezFormat
realidad obtiene 2 argumentos, el primero es a String[]
, el segundo es a String
. Si está pasando una matriz a varargs, y desea que sus elementos sean reconocidos como argumentos individuales, y también necesita agregar un argumento adicional, entonces no tiene más remedio que crear otra matriz que acomode el elemento adicional.
Aquí hay algunos métodos de ayuda útiles:
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;
}
Ahora puedes hacer lo siguiente:
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 gotchas # 3: pasar una serie de primitivas
No "funciona":
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs solo funciona con tipos de referencia. Autoboxing no se aplica a la matriz de primitivas. Los siguientes trabajos:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"