Sim, a T...
é apenas um açúcar sintático para a T[]
.
O último parâmetro formal em uma lista é especial; pode ser um parâmetro de variável arity , indicado por reticências após o tipo.
Se o último parâmetro formal for um parâmetro de variável arity do tipo T
, considerar-se-á definir um parâmetro formal do tipo T[]
. O método é então um método de variável variável . Caso contrário, é um método de aridade fixo . As invocações de um método de variável arity podem conter expressões de argumento mais reais do que parâmetros formais. Todas as expressões de argumento reais que não correspondem aos parâmetros formais que precedem o parâmetro variável arity serão avaliadas e os resultados armazenados em uma matriz que será passada para a chamada do método.
Aqui está um exemplo 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 ]"
}
E sim, o acima main
método é válido, porque, novamente, String...
é justo String[]
. Além disso, como as matrizes são covariantes, a String[]
é uma Object[]
, então você também pode chamar de ezFormat(args)
qualquer maneira.
Veja também
Dicas Varargs # 1: passagem null
Como os varargs são resolvidos é bastante complicado e, às vezes, faz coisas que podem surpreendê-lo.
Considere este exemplo:
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!!!
Devido à forma como varargs são resolvidos, os últimos invoca declaração com objs = null
, o que naturalmente causariam NullPointerException
com objs.length
. Se você deseja atribuir um null
argumento a um parâmetro varargs, pode fazer o seguinte:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Perguntas relacionadas
A seguir, é apresentado um exemplo de algumas das perguntas que as pessoas fizeram ao lidar com varargs:
Vararg dicas # 2: adicionando argumentos extras
Como você descobriu, o seguinte não "funciona":
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Devido à maneira como os varargs funcionam, ezFormat
na verdade obtém 2 argumentos, sendo o primeiro a String[]
, o segundo sendo a String
. Se você estiver passando uma matriz para varargs e quiser que seus elementos sejam reconhecidos como argumentos individuais, e também precisar adicionar um argumento extra, não terá outra opção a não ser criar outra matriz que acomode o elemento extra.
Aqui estão alguns métodos auxiliares úteis:
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;
}
Agora você pode fazer o seguinte:
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 ]"
Dicas de Varargs # 3: passando uma matriz de primitivas
Não "funciona":
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs funciona apenas com tipos de referência. A caixa automática não se aplica à matriz de primitivas. Os seguintes trabalhos:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"