Java, 3 points dans les paramètres

822

Que signifient les 3 points de la méthode suivante?

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

Réponses:

988

Cela signifie que zéro ou plusieurs objets String (ou un tableau d'entre eux) peuvent être passés comme argument (s) pour cette méthode.

Voir la section "Nombre arbitraire d'arguments" ici: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

Dans votre exemple, vous pouvez l'appeler comme suit:

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

Remarque importante: les arguments transmis de cette manière sont toujours un tableau - même s'il n'y en a qu'un. Assurez-vous de le traiter de cette façon dans le corps de la méthode.

Remarque importante 2: L'argument qui obtient le ...doit être le dernier dans la signature de la méthode. Donc, myMethod(int i, String... strings)ça va, mais myMethod(String... strings, int i)ça ne va pas.

Merci à Vash pour les clarifications dans son commentaire.

kiswa
la source
112
Vous vous trompez, dans ce "un ou plusieurs", avec varargs nous pouvons spécifier 0 ou plus, et cela doit toujours être le dernier paramètre de la méthode. La méthode x (String ... params) peut être appelée comme x () ou la méthode y (String pram, String ... params) peut être appelée comme y ("1")
Damian Leszczyński - Vash
2
Je souhaite que cela ait fonctionné aussi. myMethod ("un", "deux", "trois", nouvelle chaîne [] {"a", "b", "c" "});
2sb
2
Pourquoi avez-vous le droit de donner des paramètres à la méthode 0? Cela conduira très probablement à ArrayIndexOutOfBoundsException. Maintenant, vous devez toujours prendre ce cas en considération.
Olle Söderström
11
Parce qu'ils sont facultatifs. C'est au développeur qui a décidé d'utiliser des arguments facultatifs pour implémenter correctement la méthode pour gérer en avoir zéro ou plus.
kiswa
@ OlleSöderström Une autre raison est que le paramètre formel est converti en tableau au moment de la compilation. Cela signifie que le passage dans un tableau donne le même résultat. Comme la longueur d'un tableau n'est pas connue au moment de la compilation, la restriction de passer au moins un élément pourrait être contournée en appelant simplement someMethod(new SomeType[] { }). Ce serait un hack, non?
MC Emperor
124

Cette fonctionnalité est appelée varargs , et c'est une fonctionnalité introduite dans Java 5. Cela signifie que la fonction peut recevoir plusieurs Stringarguments:

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

Ensuite, vous pouvez utiliser le Stringvar comme tableau:

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

Cette réponse emprunte beaucoup à celle de kiswa et de Lorenzo ... ainsi qu'au commentaire de Graphain.

Cristian
la source
13
Lorsque le code atteint le bytecode, il s'agit d' un tableau. Tout le reste est une syntaxe prise en charge uniquement par le compilateur.
Donal Fellows
Cette réponse emprunte beaucoup à celle de kiswa et de Lorenzo si je lis correctement les modifications.
Matt Mitchell
3
@Graph 'est préférable de modifier votre réponse et de la rendre plus correcte que de la laisser seule. Et si une autre réponse est la source de votre amélioration, alors ça va. Au moins, il est honnête à ce sujet (et je suppose qu'il a voté pour les autres réponses qui l'ont aidé ... non?).
1
@Sera-t-il honnête après que je l'ai indiqué, ce qui est assez bien. Merci d'avoir regardé.
Matt Mitchell
23

C'est Varargs :)

Le varargs abréviation d'arguments de longueur variable est une fonctionnalité qui permet à la méthode d'accepter un nombre variable d'arguments (zéro ou plus). Avec varargs, il est devenu simple de créer des méthodes qui doivent prendre un nombre variable d'arguments. La fonction d'argument variable a été ajoutée dans Java 5.

Syntaxe de varargs

Un vararg est sécurisé par trois points de suspension (trois points) après le type de données, sa forme générale est

return_type method_name(data_type ... variableName){
}  

Besoin de varargs

Avant Java 5, au cas où il y aurait besoin d'un nombre variable d'arguments, il y avait deux façons de le gérer

Si le nombre maximal d'arguments qu'une méthode peut prendre était petit et connu, des versions surchargées de la méthode pourraient être créées. Si le nombre maximum d'arguments qu'une méthode pouvait prendre était grand ou / et inconnu, alors l'approche consistait à placer ces arguments dans un tableau et à les transmettre à une méthode qui prend le tableau comme paramètre. Ces 2 approches étaient sujettes aux erreurs - construire un tableau de paramètres à chaque fois et difficiles à maintenir - car l'ajout d'un nouvel argument peut entraîner l'écriture d'une nouvelle méthode surchargée.

Avantages des varargs

Offre une option beaucoup plus simple. Moins de code car pas besoin d'écrire des méthodes surchargées.

Exemple de 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

Le programme peut voir que la longueur est utilisée ici pour trouver le nombre d'arguments passés à la méthode. Cela est possible car les varargs sont implicitement passés sous forme de tableau. Quels que soient les arguments passés sous forme de varargs, ils sont stockés dans un tableau qui est référencé par le nom donné à varargs. Dans ce nom de tableau de programme est des valeurs. Notez également que la méthode est appelée avec un nombre d'arguments différent, appelez d'abord avec quatre arguments, puis trois arguments et ensuite avec zéro argument. Tous ces appels sont gérés par la même méthode qui prend varargs.

Restriction avec varargs

Il est possible d'avoir d'autres paramètres avec le paramètre varargs dans une méthode, mais dans ce cas, le paramètre varargs doit être le dernier paramètre déclaré par la méthode.

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

Une autre restriction avec varargs est qu'il ne doit y avoir qu'un seul paramètre varargs.

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

Surcharge des méthodes varargs

Il est possible de surcharger une méthode qui prend le paramètre varargs. La méthode Varargs peut être surchargée par -

Les types de son paramètre vararg peuvent être différents. En ajoutant d'autres paramètres. Exemple de surcharge de la méthode 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 et surcharge d'ambiguïté

Dans certains cas, l'appel peut être ambigu alors que nous avons surchargé la méthode varargs. Voyons un exemple

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

Dans ce programme, lorsque nous appelons la méthode displayData () sans aucun paramètre, il génère une erreur, car le compilateur n'est pas sûr que cet appel de méthode soit pour displayData(String ... values)oudisplayData(int ... values)

De la même façon, si nous avons des méthodes surchargées où l'une a la varargméthode d'un type et une autre méthode a un paramètre et un varargparamètre du même type, alors nous avons aussi l'ambiguïté - As Exp - displayData(int ... values)etdisplayData(int a, int ... values)

Ces deux méthodes surchargées auront toujours une ambiguïté.

SIW
la source
15

C'est la manière Java de passer des varargs (arguments de nombre variable).

Si vous êtes familier avec C, ceci est similaire à la ...syntaxe utilisée dans la printffonction:

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

mais d'une manière sûre de type: chaque argument doit être conforme au type spécifié (dans votre échantillon, ils devraient être tous String).

Voici un exemple simple de la façon dont vous pouvez utiliser des 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' ...argument est en fait un tableau, vous pouvez donc passer un String[]comme paramètre.

lornova
la source
11

On peut dire que c'est un exemple de sucre syntaxique, car il est de toute façon implémenté comme un tableau (ce qui ne signifie pas qu'il est inutile) - Je préfère passer un tableau pour le garder clair, et déclarer également des méthodes avec des tableaux de type donné. Mais plutôt une opinion qu'une réponse.

MichaelS
la source
5

Aussi pour faire la lumière, il est important de savoir que les paramètres var-arg sont limités à un et que vous ne pouvez pas avoir plusieurs paramètres var-art. Par exemple, c'est illigal:

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

Considérez-le comme le mot-clé paramsen C #, si vous venez de ce milieu :)

Ε Г И І И О
la source
Je suis programmeur C #.
Programmeur orienté vers l'argent
2

Une façon vraiment courante de voir un exemple clair de l'utilisation des trois points, il est présent dans l'une des méthodes les plus célèbres d'Android AsyncTask (qui aujourd'hui n'est pas trop utilisé à cause de RXJAVA, sans parler des composants de Google Architecture), vous pouvez trouver des milliers d'exemples à la recherche de ce terme, et la meilleure façon de comprendre et de ne plus oublier la signification des trois points est qu'ils expriment un ... doute ... comme dans le langage courant. À savoir, le nombre de paramètres à transmettre n'est pas clair, peut être 0, peut être 1, peut être plus (un tableau) ...

trocchietto
la source
1

String... est le même que 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
la source
1
Si String...est le même que String[], ne pourriez-vous pas simplement dire cela?
Scott Hunter
8
Techniquement pas vrai car String[]nécessite un argument (au moins un tableau vide) alors String...que non (voir la réponse ci-dessus).
Aurel
0

En plus des autres réponses bien écrites, un avantage que varagrsj'ai trouvé utile est que, lorsque j'appelle une méthode avec un tableau comme type de paramètre, cela enlève la douleur de créer un tableau; ajouter des éléments, puis l'envoyer. Au lieu de cela, je peux simplement appeler la méthode avec autant de valeurs que je veux; de zéro à plusieurs.

PhantomReference
la source
0
  • Cela signifie zéro ou plusieurs paramètres du même type de données.
  • Ce doit être le dernier paramètre du constructeur ou de la fonction.
  • Nous ne pouvons avoir qu'un seul paramètre de ce type dans le constructeur ou la fonction respective.

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

    }
}

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

    }
}

production:

ouais haa

ouais haa

Shubham Jain
la source
-1

Syntaxe: (Triple point ...) -> Signifie que nous pouvons ajouter zéro ou plusieurs objets passer dans un argument ou passer un tableau de type objet.

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

Définition: 1) L'argument Object ... n'est qu'une référence à un tableau d'objets.

2) ('String []' ou String ...) Il peut gérer n'importe quel nombre d'objets chaîne. En interne, il utilise un tableau d'objets de type référence.

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) Si vous voulez appeler la méthode avec un seul argument et qu'il s'agit d'un tableau, vous devez l'encapsuler explicitement dans

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

Application: Elle est principalement utilisée lorsque le nombre d'arguments est dynamique (nombre d'arguments connus au moment de l'exécution) et en surcharge. Règle générale - Dans la méthode, nous pouvons passer n'importe quel type et n'importe quel nombre d'arguments. Nous ne pouvons pas ajouter d'arguments objet (...) avant des arguments spécifiques. c'est à 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.   
Vishal Sheth
la source