Variable Argumentlisten (varargs
) als Parameter für Methoden sind seit Java 5 möglich.
Sie sind eine sehr praktische Möglichkeit, um Methoden mit einer variablen Anzahl von Parametern zu definieren.
Üblicherweise hat man eine Methode mit einem Parameter als Ausgangspunkt und möchte diese um eine weitere Variante erweitern, die mehrere Parameter akzeptiert:
public void foo(String arg) {
System.out.println(arg);
}
public void foo(String... args) {
if (args == null) {
return;
}
for (String arg : args) {
foo(arg);
}
}
Die Aufrufe beider Methoden funktionieren auf den ersten Blick auch wunderbar:
foo("bar"); // Aufruf der Methode mit einem Parameter
foo("bar", "baz"); // Delegiert auf die varargs Methode
foo(new String[]{"foo", "bar"}); // Delegiert auf die varargs Methode
foo({"foo", "bar"}); // Delegiert auf die varargs Methode
Allerdings kann es Probleme mit diesen Methoden geben. Verwenden wir ein null
als Argument,
so kann der Compiler nicht entscheiden, welche Methode aufgerufen werden soll:
foo(null); // ambiguous method call
Das Problem ist, dass der Compiler nicht weiß, ob er die Methode mit einem Parameter oder die Methode mit der variablen Argumentliste aufrufen soll.
Dies kann uns dazu nötigen, beim Einsatz von null
einen expliziten Cast zu verwenden:
foo((String) null); // Aufruf der Methode mit einem Parameter
In dynamischen Sprachen, wie Groovy kann das Problem sogar bei der Verwendung einer Variablen zur Laufzeit auftreten:
String value = null
print(value) // ambiguous method call
Weiterhin besteht nun die Möglichkeit, dass wir die Methode ohne Parameter aufrufen:
foo(); // Delegiert auf die varargs Methode
Dieser Aufruf ist in diesem Fall zwar nicht sinnvoll, aber dennoch möglich.
Daher macht es Sinn, die Methode mit der variablen Argumentliste anzupassen, um beide Probleme zugleich zu lösen:
public void foo(String arg0, String... args) {
foo(arg0);
if (args == null) {
return;
}
for (String arg : args) {
foo(arg);
}
}
Nun ist der Aufruf mit null
eindeutig und der Aufruf ohne Parameter ist per Compiler nicht mehr möglich.
foo(null); // Aufruf der Methode mit einem Parameter
foo(); // Compilerfehler
Dafür ist der Aufruf mit nur einem Parameter-Array auch per Compiler nicht mehr möglich:
foo(new String[]{"foo", "bar"}); // Compilerfehler
foo({"foo", "bar"}); // Compilerfehler