Menu

Java Varargs: Methoden, die beliebig viele Argumente entgegennehmen

Wie Javas Varargs (...) eine Methode beliebig viele Argumente annehmen lassen, wie sie zu einem Array werden, die Regel des einen Vararg ganz am Ende sowie die Stolperfallen beim leeren Aufruf und bei Mehrdeutigkeit.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Eine Methode, beliebig viele Argumente

Manchmal weißt du im Voraus nicht, wie viele Argumente eine Methode braucht. Im einen Moment willst du max(3, 9), im nächsten max(1, 7, 4, 2, 8). Ohne Varargs müsstest du für jede Anzahl eine Überladung schreiben oder den Aufrufer zwingen, ein Array zu bauen. Varargs - kurz für variable Argumente - lassen eine einzelne Methode null, ein oder viele Werte desselben Typs annehmen.

Du deklarierst sie, indem du drei Punkte (...) hinter den Parametertyp setzt:

Der Aufrufer übergibt lose Werte; innerhalb der Methode ist numbers ein echtes Array. Das ist die ganze Idee: Der Compiler bündelt die Argumente für dich in einem Array.

Varargs sind einfach ein Array

Zur Laufzeit gibt es keine Magie. Ein als int... numbers deklarierter Parameter ist genau ein int[], sobald du in der Methode bist. Du kannst seine length abfragen, darauf zugreifen und es wie jedes andere Array durchlaufen.

Da es wirklich ein Array ist, kannst du einer Varargs-Methode auch ein Array übergeben, das du bereits hast - sie akzeptiert beide Formen:

Die Regeln: zuletzt und nur einer

Zwei Regeln halten Varargs eindeutig, und der Compiler erzwingt beide:

  1. Der Varargs-Parameter muss der letzte sein. Normale Parameter kommen zuerst, dann saugt der ...-Parameter alles Übrige auf.
  2. Eine Methode darf höchstens einen Varargs-Parameter haben. Bei zweien wäre es unmöglich zu erkennen, wo der eine endet und der nächste beginnt.

Das kompiliert. Aber die Varargs zuerst zu setzen - static void log(Object... values, String level) - ist ein Kompilierfehler: varargs parameter must be the last. Der Pflichtparameter level steht immer vor dem ....

Wo du Varargs bereits benutzt

Du rufst die ganze Zeit schon Varargs-Methoden auf. System.out.printf und String.format sind die klassischen Beispiele - ihr zweiter Parameter ist Object... args:

List.of(...), Arrays.asList(...) und viele APIs im Builder-Stil sind ebenfalls Varargs. Deshalb kannst du ihnen beliebig viele Elemente übergeben, ohne selbst etwas in ein Array zu verpacken.

Varargs und Überladung

Varargs und Überladung wirken auf eine überraschende Weise zusammen. Wenn eine normale Überladung und eine Varargs-Überladung beide zu einem Aufruf passen könnten, bevorzugt Java die speziellere - die Methode mit fester Argumentanzahl gewinnt:

pick(1, 2) passt zu beiden, aber Java wählt die Überladung ohne Varargs, weil sie die genauere Passung ist. Die Varargs-Methode läuft nur, wenn keine Überladung mit fester Argumentanzahl passt. Das ist meist genau das, was du willst, bedeutet aber, dass das Hinzufügen einer Varargs-Überladung stillschweigend ändern kann, zu welcher Methode ein Aufruf aufgelöst wird.

Achte auf leere und null-Aufrufe

Zwei Stolperfallen erwischen viele. Erstens: Eine Varargs-Methode ohne Argumente aufzurufen, übergibt der Methode ein leeres Array, nicht null - also ist numbers.length gleich 0 und die Schleife tut nichts. Für den Fall ohne Argumente brauchst du keine null-Prüfung:

Zweitens: Ein wörtliches null zu übergeben ist mehrdeutig und gefährlich: Java kann count(null) als „das gesamte Varargs-Array ist null" statt als „ein null-Element" deuten, was dann eine NullPointerException wirft, wenn du seine length liest. Wenn du wirklich ein einzelnes null-Element meinst, sei explizit mit count((Object) null).

Als Nächstes: Klassen

Varargs runden ab, was du mit Methodenparametern tun kannst - flexible Argumentlisten zusätzlich zur Überladung. Bisher lebten die Methoden lose in einer Klasse mit static. Als Nächstes wirst du sehen, wie Klassen wirklich funktionieren: Daten (Felder) und Verhalten (Methoden) in eigenen Typen zu bündeln, was das Herzstück der objektorientierten Programmierung in Java ist.

Häufig gestellte Fragen

Was sind Varargs in Java?

Varargs (variable Argumente) lassen eine Methode beliebig viele Argumente desselben Typs annehmen. Du deklarierst sie, indem du ... hinter den Typ setzt: int sum(int... numbers). Der Aufrufer kann null, ein oder viele Werte übergeben, und innerhalb der Methode ist numbers ein normales Array. Es ist syntaktischer Zucker - Java fasst die losen Argumente für dich zu einem Array zusammen.

Kann eine Java-Methode mehr als einen Varargs-Parameter haben?

Nein. Eine Methode darf höchstens einen Varargs-Parameter haben, und er muss der letzte in der Parameterliste sein - zum Beispiel void log(String level, Object... values). Wäre er nicht der letzte, wüsste Java nicht, wo der Teil variabler Länge endet und der nächste Parameter beginnt. Normale Parameter stehen immer vor dem ...-Parameter.

Was ist der Unterschied zwischen Varargs und einem Array-Parameter in Java?

Zur Laufzeit sind sie nahezu identisch - ein Varargs-Parameter int... ist innerhalb der Methode ein int[]. Der Unterschied liegt an der Aufrufstelle: Mit Varargs schreibst du sum(1, 2, 3) (lose Werte), während du bei einem expliziten Array-Parameter ein Array erstellen und übergeben musst: sum(new int[]{1, 2, 3}). Eine Varargs-Methode akzeptiert auch direkt ein Array, sie ist also die flexiblere Wahl.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S