Bombentrichter
7.3.4 Variable Parameterlisten Seit der J2SE 5.0 gibt es die Möglichkeit, variable Parameterlisten zu definieren, in denen ein formaler Parameter für eine beliebige Anzahl aktueller Argumente steht. Dazu kann der letzte Parameter einer Methode (und nur dieser) nach dem Typbezeichner mit drei Punkten versehen werden. So wird angezeigt, daß an dieser Stelle beim Aufruf eine beliebige Anzahl Argumente des passenden Typs übergeben werden darf: Code: [Select]002 {003 for (int i = 0; i < args.length; ++i) {004 System.out.println(args[i]);005 }006 }Listing 7.11: Eine Methode mit einer variablen Parameterliste JDK1.1-5.0 Technisch entspricht die Deklaration der eines Arrays-Parameters, und so wird auch auf die Elemente zugegriffen. Die Vereinfachung wird sichtbar, wenn man sich den Aufruf der Methode ansieht. An dieser Stelle darf nämlich nicht nur ein einzelnes Array übergeben werden, sondern die einzelnen Elemente können auch separat angegeben werden. Dabei erzeugt das Laufzeitsystem automatisch ein Array, in das diese Werte übertragen werden. Die beiden folgenden Aufrufe sind also gleichwertig: printArgs(new String[]{"so", "wird", "es", "gemacht"});printArgs("so", "wird", "es", "gemacht");Nun wird auch deutlich, warum lediglich der letzte Parameter variabel sein darf. Andernfalls könnte der Compiler unter Umständen nicht mehr unterscheiden, welches aktuelle Argument zu welchem formalen Parameter gehört. Praktischen Nutzen haben die variablen Parameterlisten bei Anwendungen, in denen nicht von vorneherein klar ist, wieviele Argumente benötigt werden. Tatsächlich wurde ihre Entwicklung durch den Wunsch motiviert, flexible Ausgabemethoden definieren zu können, wie sie etwa in C/C++ mit der printf-Familie zur Verfügung stehen (und seit der J2SE 5.0 mit der Klasse java.util.Formatter, die in Abschnitt 11.5 beschrieben wird). Sie können dann die in diesem Fall vielfach verwendeten überladenen Methoden ersetzen (siehe Abschnitt 7.3.6). Natürlich benötigt nicht jede Methode variable Parameterlisten, sondern ihre Anwendung sollte auf Spezialfälle beschränkt bleiben. Wird eine Methode mit einem Parameter vom Typ Object... deklariert, entstehen in Zusammenhang mit dem ebenfalls seit der J2SE 5.0 verfügbaren Mechanismus des Autoboxings (siehe Abschnitt 10.2.3) Methoden, bei denen praktisch alle Typprüfungen des Compilers ausgehebelt werden. Da ein Element des Typs Object zu allen anderen Referenztypen kompatibel ist und primitive Typen dank des Autoboxings automatisch in passende Wrapper-Objekte konvertiert werden, kann an einen Parameter des Typs Object... eine beliebige Anzahl beliebiger Argumente übergeben werden. Das folgende Listing zeigt eine Methode, die numerische Argumente jeweils solange summiert, bis ein nichtnumerischer Wert übergeben wird. Dieser wird dann in einen String konvertiert und zusammen mit der Zwischensumme ausgegeben. Am Ende wird zusätzlich die Gesamtsumme ausgegeben. Nicht unbedingt eine typische Anwendung, und erst recht kein empfehlenswerter Programmierstil, aber das Listing demonstriert, wie weitreichend die Möglichkeiten dieses neuen Konzepts sind: Code: [Select]001 /* Listing0712.java */002 003 public class Listing0712004 {005 public static void registrierKasse(Object... args)006 {007 double zwischensumme = 0;008 double gesamtsumme = 0;009 for (int i = 0; i < args.length; ++i) {010 if (args[i] instanceof Number) {011 zwischensumme += ((Number)args[i]).doubleValue();012 } else {013 System.out.println(args[i] + ": " + zwischensumme);014 gesamtsumme += zwischensumme;015 zwischensumme = 0;016 }017 }018 System.out.println("Gesamtsumme: " + gesamtsumme);019 }020 021 public static void main(String[] args)022 {023 registrierKasse(024 1.45, 0.79, 19.90, "Ware",025 -3.00, 1.50, "Pfand",026 -10, "Gutschein"027 );028 }029 } Listing0712.javaDie Ausgabe des Programmes ist: Ware: 22.14Pfand: -1.5Gutschein: -10.0Gesamtsumme: 10.64
002 {003 for (int i = 0; i < args.length; ++i) {004 System.out.println(args[i]);005 }006 }
001 /* Listing0712.java */002 003 public class Listing0712004 {005 public static void registrierKasse(Object... args)006 {007 double zwischensumme = 0;008 double gesamtsumme = 0;009 for (int i = 0; i < args.length; ++i) {010 if (args[i] instanceof Number) {011 zwischensumme += ((Number)args[i]).doubleValue();012 } else {013 System.out.println(args[i] + ": " + zwischensumme);014 gesamtsumme += zwischensumme;015 zwischensumme = 0;016 }017 }018 System.out.println("Gesamtsumme: " + gesamtsumme);019 }020 021 public static void main(String[] args)022 {023 registrierKasse(024 1.45, 0.79, 19.90, "Ware",025 -3.00, 1.50, "Pfand",026 -10, "Gutschein"027 );028 }029 } Listing0712.java