Advanced   Java   Services Variable Argumentlisten (Varargs ab 1.5) Back Next Up Home


Einfürung

Mit der Version 5 bzw. 1.5 hat Java variable Argumentenlisten bei Methoden eingeführt. Damit wurde ein Feature installiert, das es bereits in C gibt, der Mutter aller modernen Programmiersprachen. Die Syntax und auch der Aufruf ist sehr einfach.

public static void varargs(int... x)
{
   for(int i=0; i < x.length ; i++)
      System.out.println(x[i]);
}

Drei Punkte nach dem (beliebigen) Datentyp und ein Bezeichner. Das war's. Im Rumpf wird dann verraten, welchen Typ die so bezeichnete Variable hat. Es handelt sich um den zur Deklaration in der Parameterliste passenden Arraytyp. Aufgerufen wird das Ganze folgendermaßen:

varargs(3, 4, 5, 6);  // 1

oder so

int x = 5, y = 6, z = 17;
varargs(3, x, 5, y, 6, z);  // 1

Im Grunde nimmt der Compiler dem Programmierer nur eine Routinearbeit ab, denn hinter den drei Punkten steckt folgende Deklarationen:

public static void varargs(int[] x)

Allerdings muß bei der letzeren Deklaration der Entwickler eine Arrayvariable übergeben. Diese Arbeit nimmt ihm der Compiler bei einer varargs-Deklaration ab indem er beim Anruf der Methode ein anonymes Array on the fly erzeugt. Die Zeile

varargs(3, x, 5, y, 6, z);

übersetzt der Compiler zu

varargs( new int[] {3, x, 5, y, 6, z} );

Eine Folgerung aus dieser Tatsache ist natürlich, daß die beiden Deklarationen

public static void varargs(int... x)

und

public static void varargs(int[] x)

nicht beide zusammen existieren können, andernfalls meldet sich der Compiler mit der Meldung

cannot declare both varargs(int[]) and varargs(int...)

Regeln


Varargs und das Überladen von Methoden

Beim Überladen von Methoden kann es zu Mehrdeutigkeiten kommen. In diesem Fall versucht der Compiler diese nach gewissen Regeln aufzulösen. Gelingt ihm das nicht, so meldet er einen Compilerfehler. Einen Fall von Mehrdeutigkeit haben wir im letzten Abschnitt festgestellt. In diesem Fall hat der Compiler die beiden Deklarationen als gleichwertig angesehen und konnte daher keine Entscheidung treffen. Es folgen einige Beispiele, bei denen der Compiler die Mehrdeutigkeiten auflösen kann.


Beispiel 1
public static void varargs1(int a, int b) // 1
{
   System.out.println("int, int");
}

public static void varargs1(int... arr) // 2
{
   System.out.println("int...");
}

Aufruf

varargs2(7, 8);

Welche Methode wird aufgerufen?


Beispiel 2
public static void varargs2(double a, double b) // 3
{
   System.out.println("int, int");
}

public static void varargs2(short... arr) // 4
{
   System.out.println("short...");
}

Aufruf

varargs2(7, 8);

Welche Methode wird aufgerufen?


Beispiel 3
public static void varargs3(Integer a, Integer b) // 5
{
   System.out.println("Integer, Integer");
}

public static void varargs3(int... arr) // 6
{
   System.out.println("int...");
}

Aufruf

varargs2(7, 8);

Welche Methode wird aufgerufen?

Der Compiler entscheidet ein jedesmal konservativ. In keinem der drei Fälle wählt der Compiler die Variante mit Varargs. Im Beispiel 1 entscheidet sich der Compiler für althergebrachte Deklaration, im Beispeil 2 bevorzugt er ein Typkonvertierung zu double (Widening), im Beispiel 3 bevorzugt er Autoboxing. Diese Regeln lassen sich im Englischen sehr prägnant ausdrücken.


Regeln beim Überladen
Valid XHTML 1.0 Strict top Back Next Up Home