Java, 3 Punkte in Parametern

822

Was bedeuten die 3 Punkte in der folgenden Methode?

public void myMethod(String... strings){
    // method body
}
Vikram
quelle

Antworten:

987

Dies bedeutet, dass null oder mehr String-Objekte (oder ein Array davon) als Argument (e) für diese Methode übergeben werden können.

Siehe den Abschnitt "Beliebige Anzahl von Argumenten" hier: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

In Ihrem Beispiel können Sie es wie folgt nennen:

myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});

Wichtiger Hinweis: Die auf diese Weise übergebenen Argumente sind immer ein Array - auch wenn es nur eines gibt. Stellen Sie sicher, dass Sie es im Methodenkörper so behandeln.

Wichtiger Hinweis 2: Das Argument, das das erhält, ...muss das letzte in der Methodensignatur sein. Also, myMethod(int i, String... strings)ist okay, aber myMethod(String... strings, int i)nicht okay.

Vielen Dank an Vash für die Klarstellungen in seinem Kommentar.

kiswa
quelle
112
Sie irren sich in diesem "einen oder mehreren" mit varargs, wir können 0 oder mehr angeben, und dies muss immer der letzte Parameter in der Methode sein. Die Methode x (String ... params) kann als x () oder die Methode y (String pram, String ... params) als y ("1") aufgerufen werden
Damian Leszczyński - Vash
2
Ich wünschte, das hätte auch funktioniert. myMethod ("eins", "zwei", "drei", neuer String [] {"a", "b", "c"});
2sb
2
Warum dürfen Sie der Methode 0 Parameter geben? Dies führt höchstwahrscheinlich zu einer ArrayIndexOutOfBoundsException. Jetzt müssen Sie diesen Fall immer berücksichtigen.
Olle Söderström
11
Weil sie optional sind. Es liegt an dem Entwickler, der sich entschieden hat, optionale Argumente zu verwenden, um die Methode ordnungsgemäß zu implementieren, um null oder mehr davon zu handhaben.
Kiswa
@ OlleSöderström Ein weiterer Grund ist, dass der formale Parameter zur Kompilierungszeit in ein Array konvertiert wird. Das bedeutet, dass das Übergeben eines Arrays das gleiche Ergebnis liefert. Da die Länge eines Arrays zur Kompilierungszeit nicht bekannt ist, könnte die Beschränkung, mindestens ein Element zu übergeben, durch einfaches Aufrufen umgangen werden someMethod(new SomeType[] { }). Das wäre ein Hack, nicht wahr?
MC Emperor
124

Diese Funktion heißt varargs und wurde in Java 5 eingeführt . Dies bedeutet, dass die Funktion mehrere StringArgumente empfangen kann :

myMethod("foo", "bar");
myMethod("foo", "bar", "baz");
myMethod(new String[]{"foo", "var", "baz"}); // you can even pass an array

Dann können Sie die StringVariable als Array verwenden:

public void myMethod(String... strings){
    for(String whatever : strings){
        // do what ever you want
    }

    // the code above is is equivalent to
    for( int i = 0; i < strings.length; i++){
        // classical for. In this case you use strings[i]
    }
}

Diese Antwort lehnt sich stark an Kiswas und Lorenzos an ... und auch an den Kommentar des Graphain.

Cristian
quelle
13
Wenn der Code auf den Bytecode trifft, handelt es sich um ein Array. Alles andere ist eine Syntax, die nur vom Compiler unterstützt wird.
Donal Fellows
Diese Antwort stammt stark von Kiswa und Lorenzo, wenn ich die Änderungen richtig lese.
Matt Mitchell
3
@Graph Es ist besser, Ihre Antwort zu bearbeiten und korrekter zu machen, als sie in Ruhe zu lassen. Und wenn eine andere Antwort die Quelle Ihrer Verbesserung ist, dann geht es. Zumindest ist er ehrlich (und ich nehme an, er hat die anderen Antworten, die ihm geholfen haben, positiv bewertet ... richtig?).
1
@ Will er ehrlich sein, nachdem ich darauf hingewiesen habe, was in Ordnung genug ist. Danke fürs schauen.
Matt Mitchell
23

Es ist Varargs :)

Die Abkürzung varargs für Argumente variabler Länge ist eine Funktion, mit der die Methode eine variable Anzahl von Argumenten (null oder mehr) akzeptieren kann. Mit varargs ist es einfach geworden, Methoden zu erstellen, die eine variable Anzahl von Argumenten annehmen müssen. Die Funktion des Variablenarguments wurde in Java 5 hinzugefügt.

Syntax von varargs

Ein Vararg wird durch drei Auslassungspunkte (drei Punkte) nach dem Datentyp getrennt, seine allgemeine Form ist

return_type method_name(data_type ... variableName){
}  

Notwendigkeit für Varargs

Vor Java 5 gab es zwei Möglichkeiten, damit umzugehen, falls eine variable Anzahl von Argumenten erforderlich war

Wenn die maximale Anzahl von Argumenten, die eine Methode annehmen kann, klein und bekannt war, können überladene Versionen der Methode erstellt werden. Wenn die maximale Anzahl von Argumenten, die eine Methode annehmen konnte, groß oder / und unbekannt war, bestand der Ansatz darin, diese Argumente in ein Array einzufügen und sie an eine Methode zu übergeben, die Array als Parameter verwendet. Diese beiden Ansätze waren fehleranfällig - sie erstellten jedes Mal ein Array von Parametern und waren schwer zu pflegen -, da das Hinzufügen eines neuen Arguments zum Schreiben einer neuen überladenen Methode führen kann.

Vorteile von Varargs

Bietet eine viel einfachere Option. Weniger Code, da keine überladenen Methoden geschrieben werden müssen.

Beispiel für Varargs

public class VarargsExample {
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 public static void main(String[] args) {
  VarargsExample vObj = new VarargsExample();
  // four args
  vObj.displayData("var", "args", "are", "passed");
  //three args
  vObj.displayData("Three", "args", "passed");
  // no-arg
  vObj.displayData();
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 
Number of arguments passed 3
Three 
args 
passed 
Number of arguments passed 0

Aus dem Programm ist ersichtlich, dass hier die Länge verwendet wird, um die Anzahl der an die Methode übergebenen Argumente zu ermitteln. Dies ist möglich, weil Varargs implizit als Array übergeben werden. Alle Argumente, die als varargs übergeben werden, werden in einem Array gespeichert, das mit dem Namen varargs bezeichnet wird. In diesem Programm enthält der Array-Name Werte. Beachten Sie auch, dass die Methode mit einer anderen Anzahl von Argumenten aufgerufen wird. Rufen Sie zuerst vier Argumente, dann drei Argumente und dann null Argumente auf. Alle diese Aufrufe werden mit derselben Methode behandelt, die varargs verwendet.

Einschränkung mit Varargs

Es ist möglich, andere Parameter mit dem Parameter varargs in einer Methode zu haben. In diesem Fall muss der Parameter varargs jedoch der letzte von der Methode deklarierte Parameter sein.

void displayValues(int a, int b, int  values) // OK
   void displayValues(int a, int b, int  values, int c) // compiler error

Eine weitere Einschränkung bei varargs besteht darin, dass nur ein varargs-Parameter vorhanden sein darf.

void displayValues(int a, int b, int  values, int  moreValues) // Compiler error

Überladen von varargs Methoden

Es ist möglich, eine Methode zu überladen, die den Parameter varargs verwendet. Die Varargs-Methode kann überladen werden durch -

Die Typen des vararg-Parameters können unterschiedlich sein. Durch Hinzufügen anderer Parameter. Beispiel für das Überladen der Varargs-Methode

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 // Method with int vararg and one more string parameter
 public void displayData(String a, int ... values){
  System.out.println(" a " + a);
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // One String param and two int args
  vObj.displayData("Test", 20, 30);
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 

Number of arguments passed 2
10 
20

 a Test
Number of arguments passed 2
20 
30 

Varargs und überladende Mehrdeutigkeit

In einigen Fällen kann der Aufruf mehrdeutig sein, während wir die varargs-Methode überladen haben. Sehen wir uns ein Beispiel an

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // This call is ambiguous
  vObj.displayData();
 }
}

Wenn wir in diesem Programm die Methode displayData () ohne Parameter aufrufen, wird ein Fehler ausgegeben, da der Compiler nicht sicher ist, ob dieser Methodenaufruf für displayData(String ... values)oder istdisplayData(int ... values)

Genauso wie wir überladene Methoden haben, bei denen eine die varargMethode eines Typs und eine andere Methode einen Parameter und einen varargParameter desselben Typs hat, dann haben wir auch die Mehrdeutigkeit - As Exp - displayData(int ... values)unddisplayData(int a, int ... values)

Diese beiden überladenen Methoden sind immer mehrdeutig.

SIW
quelle
15

Dies ist die Java-Methode zum Übergeben von Varargs (Argumenten mit variabler Anzahl).

Wenn Sie mit C vertraut sind, ähnelt dies der verwendeten ...Syntax der printfFunktion:

int printf(const char * format, ...);

aber auf typsichere Weise: Jedes Argument muss dem angegebenen Typ entsprechen (in Ihrem Beispiel sollten es alle sein String).

Dies ist ein einfaches Beispiel dafür, wie Sie varargs verwenden können :

class VarargSample {

   public static void PrintMultipleStrings(String... strings) {
      for( String s : strings ) {
          System.out.println(s);
      }
   }

   public static void main(String[] args) {
      PrintMultipleStrings("Hello", "world");
   }
}

Das ...Argument ist eigentlich ein Array, daher können Sie a String[]als Parameter übergeben.

lornova
quelle
11

Es ist wohl ein Beispiel für syntaktischen Zucker, da es sowieso als Array implementiert ist (was nicht bedeutet, dass es nutzlos ist). Ich bevorzuge es, ein Array zu übergeben, um es klar zu halten, und Methoden mit Arrays eines bestimmten Typs zu deklarieren. Eher eine Meinung als eine Antwort.

MichaelS
quelle
5

Um etwas Licht ins Dunkel zu bringen, ist es wichtig zu wissen, dass die var-arg-Parameter auf einen beschränkt sind und Sie nicht mehrere var-art-Parameter haben können. Zum Beispiel ist dies illigal:

public void myMethod(String... strings, int ... ints){
// method body
}
Mr.Q.
quelle
4

Betrachten Sie es einfach als das Schlüsselwort paramsin C #, wenn Sie aus diesem Hintergrund kommen :)

Ε Г И І І О
quelle
Ich bin ein C # -Programmierer.
Geldorientierter Programmierer
2

Ein wirklich häufiger Weg, um ein klares Beispiel für die Verwendung der drei Punkte zu sehen, ist in einer der bekanntesten Methoden in Android AsyncTask vorhanden (die heute aufgrund von RXJAVA nicht allzu häufig verwendet wird, ganz zu schweigen von den Google Architecture-Komponenten). Sie können Tausende von Beispielen finden, die nach diesem Begriff suchen, und der beste Weg, die Bedeutung der drei Punkte zu verstehen und nie mehr zu vergessen, besteht darin, dass sie einen ... Zweifel ... ausdrücken, genau wie in der gemeinsamen Sprache. Es ist nämlich nicht klar, wie viele Parameter übergeben werden müssen, könnte 0 sein, könnte 1 sein, könnte mehr sein (ein Array) ...

trocchietto
quelle
1

String... ist das gleiche wie String[]

import java.lang.*;

public class MyClassTest {

    //public static void main(String... args) { 

    public static void main(String[] args) {
        for(String str: args) {
            System.out.println(str);
        }
    }
}
Uddhav Gautam
quelle
1
Wenn String...es dasselbe ist wie String[], kannst du das nicht einfach sagen?
Scott Hunter
8
Technisch nicht wahr, da String[]ein Argument erforderlich ist (mindestens ein leeres Array), während String...dies nicht der Fall ist (siehe Antwort oben).
Aurel
0

Neben den anderen gut geschriebenen Antworten ist ein Vorteil, den varagrsich als nützlich empfunden habe, dass das Aufrufen einer Methode mit Array als Parametertyp den Aufwand beim Erstellen eines Arrays verringert. Elemente hinzufügen und dann senden. Stattdessen kann ich die Methode einfach mit so vielen Werten aufrufen, wie ich möchte. von null bis viele.

PhantomReferenz
quelle
0
  • Es bedeutet null oder mehrere Parameter desselben Datentyps.
  • Es muss der letzte Parameter des Konstruktors oder der Funktion sein.
  • Wir können nur einen dieser Typparameter im jeweiligen Konstruktor oder in der jeweiligen Funktion haben.

Beispiel 1:

public class quest1 {

    public quest1(String... mynum) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1();

        quest1 q1=new quest1("hello");

    }
}

Beispiel 2:

public class quest1 {

    public quest1(int... at) {
        System.out.println("yee haa");
    }

    public quest1(String... at) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1("value");

        quest1 q1=new quest1(1);

    }

    public void name(String ... s) {

    }
}

Ausgabe:

yee haa

yee haa

Shubham Jain
quelle
-1

Syntax: (Triple dot ...) -> Bedeutet, dass wir null oder mehr Objekte hinzufügen können, die in Argumenten übergeben werden, oder ein Array vom Typ Objekt übergeben können.

public static void main(String[] args){}
public static void main(String... args){}

Definition: 1) Das Object ... -Argument ist nur eine Referenz auf ein Array von Objekten.

2) ('String []' oder String ...) Es kann eine beliebige Anzahl von String-Objekten verarbeiten. Intern wird ein Array von Referenztypobjekten verwendet.

i.e. Suppose we pass an Object array to the ... argument - will the resultant argument value be a two-dimensional array - because an Object[] is itself an Object:

3) Wenn Sie die Methode mit einem einzelnen Argument aufrufen möchten und es sich zufällig um ein Array handelt, müssen Sie es explizit einschließen

another. method(new Object[]{array}); 
OR 
method((Object)array), which will auto-wrap.

Anwendung: Wird hauptsächlich verwendet, wenn die Anzahl der Argumente dynamisch ist (Anzahl der zur Laufzeit bekannten Argumente) und überschrieben wird. Allgemeine Regel - In der Methode können beliebige Typen und beliebig viele Argumente übergeben werden. Wir können keine Objektargumente (...) vor bestimmten Argumenten hinzufügen. dh

void m1(String ..., String s) this is a wrong approach give syntax error.
void m1(String s, String ...); This is a right approach. Must always give last order prefernces.   
Vishal Sheth
quelle