Ja, a T...
ist nur ein syntaktischer Zucker für a T[]
.
Der letzte formale Parameter in einer Liste ist speziell. Es kann sich um einen variablen Aritätsparameter handeln , der durch eine Elipse nach dem Typ angezeigt wird.
Wenn der letzte formale Parameter ein variabler Aritätsparameter vom Typ ist T
, wird davon ausgegangen, dass er einen formalen Parameter vom Typ definiert T[]
. Die Methode ist dann eine Methode mit variabler Arität . Ansonsten handelt es sich um eine Methode mit fester Arität . Aufrufe einer variablen Aritätsmethode können mehr tatsächliche Argumentausdrücke als formale Parameter enthalten. Alle tatsächlichen Argumentausdrücke, die nicht den formalen Parametern vor dem Variablenaritätsparameter entsprechen, werden ausgewertet und die Ergebnisse in einem Array gespeichert, das an den Methodenaufruf übergeben wird.
Hier ist ein Beispiel zur Veranschaulichung:
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 ]"
}
Und ja, die obige main
Methode ist gültig, weil sie wieder String...
gerecht ist String[]
. Da Arrays kovariant sind, String[]
ist a auch ein Object[]
, sodass Sie auch in ezFormat(args)
beide Richtungen aufrufen können.
Siehe auch
Varargs Fallstricke # 1: vorbei null
Wie Varargs gelöst werden, ist ziemlich kompliziert und manchmal macht es Dinge, die Sie überraschen können.
Betrachten Sie dieses Beispiel:
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!!!
Aufgrund wie varargs aufgelöst werden, die letzte Anweisung ruft mit objs = null
, was natürlich dazu führen würde , NullPointerException
mit objs.length
. Wenn Sie null
einem varargs-Parameter ein Argument geben möchten, haben Sie folgende Möglichkeiten:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Verwandte Fragen
Das Folgende ist ein Beispiel für einige der Fragen, die Menschen beim Umgang mit Varargs gestellt haben:
Vararg Fallstricke # 2: Hinzufügen zusätzlicher Argumente
Wie Sie herausgefunden haben, "funktioniert" Folgendes nicht:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Aufgrund der Funktionsweise von varargs werden ezFormat
tatsächlich zwei Argumente angezeigt , von denen das erste a String[]
und das zweite a ist String
. Wenn Sie ein Array an varargs übergeben und möchten, dass seine Elemente als einzelne Argumente erkannt werden, und Sie auch ein zusätzliches Argument hinzufügen müssen, haben Sie keine andere Wahl, als ein anderes Array zu erstellen , das das zusätzliche Element enthält.
Hier sind einige nützliche Hilfsmethoden:
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;
}
Jetzt können Sie Folgendes tun:
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 Fallstricke # 3: Übergeben einer Reihe von Grundelementen
Es "funktioniert" nicht:
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs funktioniert nur mit Referenztypen. Autoboxing gilt nicht für eine Reihe von Grundelementen. Folgendes funktioniert:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"