Tak, a T...
jest tylko cukrem syntaktycznym dla T[]
.
Ostatni parametr formalny na liście jest specjalny; może to być zmienny parametr arity , wskazany przez elipsis następujący po typie.
Jeśli ostatnim parametrem formalnym jest zmienny parametr arity typu T
, rozważa się zdefiniowanie formalnego parametru typu T[]
. Metoda ta jest wówczas metodą zmienną . W przeciwnym razie jest to metoda o ustalonej wartości . Wywołania metody zmiennej arity mogą zawierać więcej rzeczywistych wyrażeń argumentów niż parametrów formalnych. Wszystkie rzeczywiste wyrażenia argumentów, które nie odpowiadają formalnym parametrom poprzedzającym zmienny parametr arity, zostaną ocenione, a wyniki zapisane w tablicy, która zostanie przekazana do wywołania metody.
Oto przykład ilustrujący:
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 ]"
}
I tak, powyższa main
metoda jest poprawna, ponieważ znowu String...
jest słuszna String[]
. Ponadto, ponieważ tablice są kowariantne, a String[]
jest an Object[]
, więc możesz także zadzwonić w ezFormat(args)
obie strony.
Zobacz też
Varargs gotchas # 1: pasujący null
Sposób rozwiązywania vararg jest dość skomplikowany i czasami robi rzeczy, które mogą cię zaskoczyć.
Rozważ ten przykład:
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!!!
Ze względu na to, jak varargs są rozwiązane, ostatnie wywołuje Oświadczenie objs = null
, które oczywiście mogłyby spowodować NullPointerException
z objs.length
. Jeśli chcesz podać jeden null
argument parametrowi varargs, możesz wykonać jedną z następujących czynności:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Powiązane pytania
Poniżej znajduje się próbka niektórych pytań zadawanych przez ludzi podczas obsługi varargs:
Vararg gotchas # 2: dodając dodatkowe argumenty
Jak się dowiedziałeś, następujące „nie działa”:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Ze względu na sposób działania varargs, ezFormat
faktycznie dostaje 2 argumenty, pierwszy to a String[]
, a drugi to String
. Jeśli przekazujesz tablicę do varargs i chcesz, aby jej elementy były rozpoznawane jako pojedyncze argumenty, a także musisz dodać dodatkowy argument, nie masz innego wyjścia, jak stworzyć inną tablicę, która pomieści dodatkowy element.
Oto kilka przydatnych metod pomocniczych:
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;
}
Teraz możesz wykonać następujące czynności:
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: przekazując szereg prymitywów
To nie „działa”:
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs działa tylko z typami referencyjnymi. Autoboxing nie dotyczy tablicy prymitywów. Następujące prace:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"