Java, 3 punti nei parametri


822

Cosa significano i 3 punti nel seguente metodo?

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

Risposte:


987

Significa che zero o più oggetti String (o una loro matrice) possono essere passati come argomento (i) per quel metodo.

Vedi la sezione "Numero arbitrario di argomenti" qui: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

Nel tuo esempio, potresti chiamarlo come uno dei seguenti:

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

Nota importante: gli argomenti passati in questo modo è sempre un array, anche se ce n'è solo uno. Assicurati di trattarlo in questo modo nel corpo del metodo.

Nota importante 2: l'argomento che ottiene il ...deve essere l'ultimo nella firma del metodo. Quindi myMethod(int i, String... strings)va bene, ma myMethod(String... strings, int i)non va bene.

Grazie a Vash per i chiarimenti nel suo commento.


112
Ti sbagli, in quello "uno o più", con varargs possiamo specificare 0 o più, e questo deve essere sempre l'ultimo parametro nel metodo. Il metodo x (String ... params) può essere chiamato come x () o il metodo y (String pram, String ... params) può essere chiamato come y ("1")
Damian Leszczyński - Vash

2
Vorrei che anche questo avrebbe funzionato. myMethod ("one", "two", "three", new String [] {"a", "b", "c" "});
2sb

2
Perché sei autorizzato a fornire i parametri del metodo 0? Ciò porterà probabilmente a ArrayIndexOutOfBoundsException. Ora devi sempre prendere in considerazione quel caso.
Olle Söderström,

11
Perché sono opzionali. Spetta allo sviluppatore che ha deciso di utilizzare argomenti opzionali per implementare correttamente il metodo per gestirne zero o più.
kiswa,

@ OlleSöderström Un altro motivo è che il parametro formale viene convertito in un array in fase di compilazione. Ciò significa che il passaggio in un array produce lo stesso risultato. Poiché la lunghezza di un array non è nota al momento della compilazione, la restrizione al passaggio di almeno un elemento potrebbe essere aggirata semplicemente chiamando someMethod(new SomeType[] { }). Sarebbe un trucco, no?
MC Emperor

124

Questa funzione è chiamata varargs ed è una funzionalità introdotta in Java 5. Ciò significa che la funzione può ricevere più Stringargomenti:

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

Quindi, è possibile utilizzare Stringvar come un array:

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]
    }
}

Questa risposta prende in prestito pesantemente da Kiswa e da Lorenzo ... e anche dal commento di Graphain.


13
Quando il codice raggiunge il bytecode, è un array. Tutto il resto è sintassi supportata solo dal compilatore.
Donal Fellows,

Questa risposta prende in prestito pesantemente da Kiswa e da Lorenzo se leggo correttamente le modifiche.
Matt Mitchell,

3
@Graph È meglio modificare la tua risposta e renderla più corretta che lasciarla sola. E se un'altra risposta è la fonte del tuo miglioramento, così va. Almeno ne è onesto (e presumo abbia votato a favore delle altre risposte che lo hanno aiutato ... giusto?).

1
@Sarà onesto dopo che l'ho sottolineato che va abbastanza bene. Grazie per aver guardato.
Matt Mitchell,

23

Sono Varargs :)

La sigla varargs per argomenti a lunghezza variabile è una funzione che consente al metodo di accettare un numero variabile di argomenti (zero o più). Con varargs è diventato semplice creare metodi che richiedono un numero variabile di argomenti. La funzionalità dell'argomento variabile è stata aggiunta in Java 5.

Sintassi di varargs

Un vararg è secificato da tre puntini di sospensione (tre punti) dopo il tipo di dati, la sua forma generale è

return_type method_name(data_type ... variableName){
}  

Necessità di varargs

Prima di Java 5, nel caso in cui fosse necessario un numero variabile di argomenti, c'erano due modi per gestirlo

Se il numero massimo di argomenti, un metodo può assumere era piccolo e noto, è possibile creare versioni sovraccaricate del metodo. Se il numero massimo di argomenti che un metodo potrebbe prendere era grande o / e sconosciuto, l'approccio consisteva nel mettere quegli argomenti in un array e passarli a un metodo che prende l'array come parametro. Questi 2 approcci erano soggetti a errori - costruendo una serie di parametri ogni volta e difficili da mantenere - poiché l'aggiunta di nuovi argomenti potrebbe comportare la scrittura di un nuovo metodo sovraccarico.

Vantaggi di varargs

Offre un'opzione molto più semplice. Meno codice in quanto non è necessario scrivere metodi sovraccarichi.

Esempio di 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

Dal programma si può vedere che qui viene usata la lunghezza per trovare il numero di argomenti passati al metodo. È possibile perché i vararg vengono passati implicitamente come array. Qualsiasi argomento venga passato come varargs viene archiviato in un array a cui fa riferimento il nome assegnato a varargs. In questo programma il nome dell'array è valori. Si noti inoltre che il metodo viene chiamato con un numero diverso di argomenti, prima chiamare con quattro argomenti, quindi tre argomenti e quindi con zero argomenti. Tutte queste chiamate sono gestite con lo stesso metodo che accetta varargs.

Restrizione con varargs

È possibile avere altri parametri con parametro varargs in un metodo, tuttavia in tal caso, il parametro varargs deve essere l'ultimo parametro dichiarato dal metodo.

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

Un'altra limitazione con varargs è che ci deve essere solo un parametro varargs.

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

Sovraccarico di metodi varargs

È possibile sovraccaricare un metodo che accetta il parametro varargs. Il metodo Varargs può essere sovraccaricato di -

I tipi del suo parametro vararg possono essere diversi. Aggiungendo altri parametri. Esempio di sovraccarico del metodo varargs

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 e sovraccarico di ambiguità

In alcuni casi la chiamata può essere ambigua mentre abbiamo sovraccaricato il metodo varargs. Vediamo un esempio

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();
 }
}

In questo programma quando effettuiamo una chiamata al metodo displayData () senza alcun parametro genera errore, perché il compilatore non è sicuro se questa chiamata al metodo sia per displayData(String ... values) odisplayData(int ... values)

Allo stesso modo se abbiamo metodi sovraccarichi in cui uno ha il varargmetodo di un tipo e un altro metodo ha un parametro evararg parametro dello stesso tipo, allora abbiamo anche l'ambiguità - Come Exp - displayData(int ... values)edisplayData(int a, int ... values)

Questi due metodi sovraccarichi avranno sempre ambiguità.


15

Questo è il modo Java per passare varargs (argomenti con numeri variabili).

Se hai familiarità con C, è simile alla ...sintassi utilizzata per la printffunzione:

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

ma in modo sicuro: ogni argomento deve essere conforme al tipo specificato (nel tuo campione, dovrebbero essere tutti String).

Questo è un semplice esempio di come è possibile utilizzare varargs :

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");
   }
}

L' ...argomento è in realtà un array, quindi è possibile passare a String[]come parametro.


11

Probabilmente, è un esempio di zucchero sintattico, poiché è comunque implementato come un array (il che non significa che sia inutile) - Preferisco passare un array per mantenerlo chiaro, e anche dichiarare metodi con array di tipo dato. Piuttosto un'opinione che una risposta, però.


5

Inoltre, per far luce, è importante sapere che i parametri var-arg sono limitati a uno e non è possibile avere diversi parametri var-art. Ad esempio questo è illigale:

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


2

Un modo davvero comune per vedere un chiaro esempio dell'uso dei tre punti è presente in uno dei metodi più famosi in Android AsyncTask (che oggi non viene utilizzato troppo a causa di RXJAVA, per non parlare dei componenti di Google Architecture), puoi trovare migliaia di esempi che cercano questo termine e il modo migliore per capire e non dimenticare più il significato dei tre punti è che esprimono un ... dubbio ... proprio come nel linguaggio comune. Vale a dire non è chiaro il numero di parametri che devono essere passati, potrebbe essere 0, potrebbe essere 1 potrebbe essere più (un array) ...


1

String... equivale a 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);
        }
    }
}

1
Se String...è lo stesso String[], non potresti semplicemente dirlo?
Scott Hunter,

8
Tecnicamente non è vero perché String[]richiede un argomento (almeno un array vuoto) mentre String...non lo fa (vedi la risposta sopra).
Aurel,

0

Aggiungendo alle altre risposte ben scritte, un vantaggio che varagrsho trovato utile è che, quando chiamo un metodo con array come tipo di parametro, toglie il dolore di creare un array; aggiungere elementi e quindi inviarlo. Invece, posso semplicemente chiamare il metodo con tutti i valori che voglio; da zero a molti.


0
  • Significa zero o più parametri dello stesso tipo di dati.
  • Deve essere l'ultimo parametro del costruttore o della funzione.
  • Possiamo avere solo uno di questi parametri di tipo nel rispettivo costruttore o funzione.

Esempio 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");

    }
}

Esempio 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) {

    }
}

produzione:

yee haa

yee haa


-1

Sintassi: (punto triplo ...) -> Significa che possiamo aggiungere zero o più oggetti passare in un argomento o passare una matrice di tipo oggetto.

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

Definizione: 1) L'argomento Object ... è solo un riferimento a una matrice di oggetti.

2) ('String []' o String ...) Può gestire qualsiasi numero di oggetti stringa. Internamente utilizza una matrice di oggetti del tipo di riferimento.

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) Se vuoi chiamare il metodo con un singolo argomento e capita che sia un array, devi racchiuderlo esplicitamente

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

Applicazione: utilizzato principalmente quando il numero di argomenti è dinamico (numero di argomenti conosciuti in fase di esecuzione) e in sostituzione. Regola generale : nel metodo possiamo passare qualsiasi tipo e qualsiasi numero di argomenti. Non è possibile aggiungere argomenti oggetto (...) prima di argomenti specifici. vale a dire

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.   
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.