web-dev-qa-db-fra.com

Quand utilisez-vous varargs en Java?

J'ai peur des varargs. Je ne sais pas comment les utiliser.

De plus, il est dangereux de laisser les gens passer autant d'arguments qu'ils le souhaitent.

Quel exemple de contexte serait un bon endroit pour les utiliser?

189
Harry Quince

Les variables sont utiles pour toute méthode devant traiter un nombre indéterminé d'objets . Un bon exemple est String.format . La chaîne de format peut accepter un nombre illimité de paramètres. Vous avez donc besoin d'un mécanisme pour transmettre un nombre illimité d'objets.

_String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
_
150
Andy White

Une bonne règle serait:

"Utilisez varargs pour toute méthode (ou constructeur) nécessitant un tableau de T (quel que soit le type utilisé) en entrée".

Cela facilitera les appels à ces méthodes (inutile de faire new T[]{...}).

Vous pouvez étendre cette règle pour inclure les méthodes avec un argument List<T>, à condition que cet argument ne soit que pour une entrée (c'est-à-dire que la liste n'est pas modifiée par la méthode).

De plus, je m'abstiendrais d'utiliser f(Object... args) parce que cela glissait vers un mode de programmation avec des API peu claires.

En termes d'exemples, je l'ai utilisé dans DesignGridLayout , où je peux ajouter plusieurs JComponents dans un appel:

layout.row().grid(new JLabel("Label")).add(field1, field2, field3);

Dans le code ci-dessus, la méthode add () est définie par add(JComponent... components).

Enfin, la mise en œuvre de telles méthodes doit tenir compte du fait qu’elle peut être appelée avec un vararg vide! Si vous voulez imposer au moins un argument, alors vous devez utiliser un truc laid comme:

void f(T arg1, T... args) {...}

Je considère cette astuce moche, car la mise en oeuvre de la méthode sera moins simple que d'avoir simplement T... args dans sa liste d'arguments.

J'espère que cela aide à clarifier le point sur les varargs.

78
jfpoilpret

J'utilise fréquemment varargs pour la sortie dans les journaux à des fins de débogage.

Presque toutes les classes de mon application ont une méthode debugPrint ():

private void debugPrint(Object... msg) {
    for (Object item : msg) System.out.print(item);
    System.out.println();
}

Ensuite, dans les méthodes de la classe, j'ai des appels comme celui-ci:

debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
    serialNo, ", the grade is ", grade);

Lorsque je suis convaincu que mon code fonctionne, je le commente dans la méthode debugPrint () afin que les journaux ne contiennent pas trop d'informations superflues et indésirables, mais je peux laisser les appels individuels à debugPrint () non commentés. Plus tard, si je trouve un bogue, je ne commente pas le code debugPrint () et tous mes appels à debugPrint () sont réactivés.

Bien sûr, je pourrais tout aussi bien éviter Varargs et procéder comme suit:

private void debugPrint(String msg) {
    System.out.println(msg);
}

debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
    + serialNo + ", the grade is " + grade);

Cependant, dans ce cas, lorsque je commente le code debugPrint (), le serveur doit toujours résoudre le problème de la concaténation de toutes les variables dans chaque appel à debugPrint (), même si rien n’est fait avec la chaîne résultante. Si j'utilise varargs, cependant, le serveur n'a qu'à les mettre dans un tableau avant de réaliser qu'il n'en a pas besoin. Beaucoup de temps est enregistré.

34
bob

Varargs peut être utilisé lorsque nous ne sommes pas sûr du nombre d'arguments à transmettre dans une méthode. Il crée un tableau de paramètres de longueur non spécifiée en arrière-plan et un tel paramètre peut être traité comme un tableau au moment de l'exécution.

Si nous avons une méthode surchargée pour accepter un nombre différent de paramètres, alors au lieu de surcharger la méthode à des moments différents, nous pouvons simplement utiliser le concept varargs.

De même, lorsque le type des paramètres variera, l'utilisation de "Object ... test" simplifiera beaucoup le code.

Par exemple:

public int calculate(int...list) {
    int sum = 0;
    for (int item : list) {
        sum += item;
    }
    return sum;
}

Ici, indirectement, un tableau de type int (liste) est passé en tant que paramètre et traité comme un tableau dans le code.

Pour une meilleure compréhension, suivez ce lien (cela m’a beaucoup aidé à comprendre clairement ce concept): http://www.javadb.com/using-varargs-in-Java

P.S: Même moi, j’avais peur d’utiliser des varargs quand je ne le savais pas. Mais maintenant je suis habitué. Comme il est dit: "Nous nous accrochons au connu, craignant l'inconnu", utilisez-le autant que vous le pouvez et vous allez commencer à aimer vous aussi :)

12
Sarvan

Varargs est la fonctionnalité ajoutée dans Java version 1.5.

Pourquoi utiliser ceci?

  1. Et si vous ne connaissiez pas le nombre d'arguments à passer pour une méthode?
  2. Et si vous voulez passer un nombre illimité d'arguments à une méthode?

Comment ça marche?

Il crée un tableau avec les arguments donnés et le passe à la méthode.

Exemple :

public class Solution {



    public static void main(String[] args) {
        add(5,7);
        add(5,7,9);
    }

    public static void add(int... s){
        System.out.println(s.length);
        int sum=0;
        for(int num:s)
            sum=sum+num;
        System.out.println("sum is "+sum );
    }

}

Sortie:

2

la somme est 12

3

la somme est 21

11
Arun Prakash

J'ai aussi une peur liée à varargs:

Si l'appelant transmet un tableau explicite à la méthode (par opposition à plusieurs paramètres), vous recevrez une référence partagée à ce tableau.

Si vous avez besoin de stocker ce tableau en interne, vous pouvez le cloner d’abord pour éviter que l’appelant ne le modifie plus tard.

 Object[] args = new Object[] { 1, 2, 3} ;

 varArgMethod(args);  // not varArgMethod(1,2,3);

 args[2] = "something else";  // this could have unexpected side-effects

Bien que ce ne soit pas vraiment différent de transmettre n'importe quel type d'objet dont l'état pourrait changer plus tard, étant donné que le tableau est généralement (dans le cas d'un appel avec plusieurs arguments au lieu d'un tableau) un nouvel objet créé par le compilateur en interne que vous pouvez en toute sécurité. utiliser, c'est certainement un comportement inattendu.

5
Thilo

J'utilise fréquemment varargs pour les constructeurs pouvant prendre une sorte d'objet filtre. Par exemple, une grande partie de notre système basé sur Hadoop est basé sur un mappeur qui gère la sérialisation et la désérialisation d'éléments en JSON, et applique un certain nombre de processeurs qui prennent chacun un élément de contenu et le modifient et le renvoient, ou retournent la valeur null. rejeter.

1
Kevin Peterson

Dans Java doc de Var-Args, l'utilisation de var args est très claire:

http://docs.Oracle.com/javase/1.5.0/docs/guide/language/varargs.html

à propos de l'utilisation, il est dit:

"Alors, quand devriez-vous utiliser varargs? En tant que client, vous devez en tirer parti dès que l'API les propose. Les principales utilisations des API principales incluent la réflexion, le formatage des messages et la nouvelle fonction printf. En tant que concepteur d'API, vous devez les utiliser avec parcimonie, lorsque les avantages sont véritablement probants. En règle générale, vous ne devriez pas surcharger une méthode varargs, sinon les programmeurs auront des difficultés à déterminer le type de surcharge appelé. "

1
Surendra