Ja, eine T...
ist nur ein syntaktischer Zucker für eine T[]
.
Der letzte formale Parameter in einer Liste ist etwas Besonderes; er kann ein Arität der Variablen Parameter, gekennzeichnet durch einen Auslassungspunkt nach dem Typ.
Wenn der letzte formale Parameter ein variabler Aritätsparameter des Typs T
wird davon ausgegangen, dass er einen formalen Parameter des Typs T[]
. Die Methode ist dann eine Arität der Variablen Methode. Andernfalls ist es eine feste Arität Methode. Aufrufe einer Methode mit variabler Arität 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 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 oben genannten main
Methode ist gültig, weil wieder, String...
ist nur String[]
. Da Arrays außerdem kovariant sind, ist eine String[]
ist ein Object[]
so können Sie auch ezFormat(args)
so oder so.
Siehe auch
Varargs-Fehler Nr. 1: Passieren null
Die Auflösung von varargs ist recht kompliziert, und manchmal werden Dinge getan, die Sie vielleicht überraschen.
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 der Art und Weise, wie varargs aufgelöst werden, ruft die letzte Anweisung mit objs = null
was natürlich dazu führen würde NullPointerException
con objs.length
. Wenn Sie eine geben wollen null
Argument zu einem varargs-Parameter zu machen, können Sie eine der folgenden Möglichkeiten nutzen:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Verwandte Fragen
Im Folgenden finden Sie einige Beispiele für Fragen, die im Zusammenhang mit varargs gestellt wurden:
Vararg-Fehler Nr. 2: Hinzufügen zusätzlicher Argumente
Wie Sie festgestellt haben, "funktioniert" das Folgende nicht:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Wegen der Art und Weise, wie varargs funktionieren, ezFormat
bekommt eigentlich 2 Argumente, das erste ist ein String[]
, die zweite ist eine String
. Wenn Sie ein Array an varargs übergeben und möchten, dass dessen Elemente als einzelne Argumente erkannt werden, und Sie außerdem ein zusätzliches Argument hinzufügen müssen, dann haben Sie keine andere Wahl als anderes Array die das zusätzliche Element aufnimmt.
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-Fehler Nr. 3: Übergabe eines Arrays von Primitiven
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 Arrays von Primitiven. Das Folgende funktioniert:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"