J'ai peur des varargues. Je ne sais pas à quoi les utiliser.
De plus, il semble dangereux de laisser les gens passer autant d'arguments qu'ils le souhaitent.
Quel est l'exemple d'un contexte qui serait un bon endroit pour les utiliser ?
J'ai peur des varargues. Je ne sais pas à quoi les utiliser.
De plus, il semble dangereux de laisser les gens passer autant d'arguments qu'ils le souhaitent.
Quel est l'exemple d'un contexte qui serait un bon endroit pour les utiliser ?
Les varargs sont utiles pour toute méthode qui doit 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. Il faut donc un mécanisme permettant de 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);
etc.
Une bonne règle de base serait :
"Utilisez les varargs pour toute méthode (ou constructeur) qui nécessite un tableau de T (quel que soit le type de T) en entrée".
Cela facilitera les appels à ces méthodes (pas besoin de faire new T[]{...}
).
Vous pouvez étendre cette règle pour inclure les méthodes avec un nom de domaine de type List<T>
à condition que cet argument soit réservé à l'entrée (c'est-à-dire que la liste ne soit pas modifiée par la méthode).
En outre, je m'abstiendrais d'utiliser f(Object... args)
parce qu'il glisse vers un mode de programmation avec des API peu claires.
En termes d'exemples, je l'ai utilisé dans les domaines suivants DesignGridLayout où je peux ajouter plusieurs JComponent
en un seul appel :
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
Dans le code ci-dessus, la méthode add() est définie comme suit add(JComponent... components)
.
Enfin, l'implémentation de telles méthodes doit prendre en compte le fait qu'elle peut être appelée avec une vararg vide ! Si vous voulez imposer au moins un argument, alors vous devez utiliser un truc laid tel que :
void f(T arg1, T... args) {...}
Je considère que cette astuce est moche parce que l'implémentation de la méthode sera moins simple que si l'on avait juste T... args
dans sa liste d'arguments.
J'espère que cela aidera à clarifier le point sur les varargs.
J'utilise fréquemment les varargs pour les sorties 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 ceux qui suivent :
debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
serialNo, ", the grade is ", grade);
Lorsque je suis convaincu que mon code fonctionne, je commente le code de la méthode debugPrint() afin que les journaux ne contiennent pas trop d'informations étrangères et indésirables, mais je peux laisser les appels individuels à debugPrint() non commentés. Plus tard, si je trouve un bug, il me suffit de décommenter le code de la méthode debugPrint(), et tous mes appels à debugPrint() sont réactivés.
Bien sûr, je pourrais tout aussi bien éviter les varargs et faire ce qui suit à la place :
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 encore concaténer toutes les variables à chaque appel à debugPrint(), même si rien n'est fait avec la chaîne résultante. En revanche, si j'utilise des varargues, le serveur n'a qu'à les placer dans un tableau avant de se rendre compte qu'il n'en a pas besoin. Cela permet de gagner beaucoup de temps.
Varargs peut être utilisé lorsque nous ne sommes pas sûrs du nombre d'arguments à passer 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 lors de l'exécution.
Si nous avons une méthode qui est surchargée pour accepter un nombre différent de paramètres, alors au lieu de surcharger la méthode plusieurs fois, nous pouvons simplement utiliser le concept de varargs.
De même, lorsque le type des paramètres varie, l'utilisation de "Object...test" simplifie grandement 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 paramètre et est traité comme un tableau dans le code.
Pour une meilleure compréhension, suivez ce lien (il 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 les varargs quand je ne les connaissais pas. Mais maintenant je m'y suis habitué. Comme il est dit : "Nous nous accrochons à ce qui est connu, nous avons peur de l'inconnu", alors utilisez-le autant que vous le pouvez et vous aussi vous commencerez à l'aimer :)
J'ai aussi une peur liée aux varargues :
Si l'appelant transmet un tableau explicite à la méthode (par opposition à des paramètres multiples), vous recevrez une référence partagée à ce tableau.
Si vous avez besoin de stocker ce tableau en interne, vous pourriez vouloir le cloner d'abord pour éviter que l'appelant puisse le modifier 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 cela ne soit pas vraiment différent de passer dans n'importe quel type d'objet dont l'état pourrait changer plus tard, puisque le tableau est généralement (dans le cas d'un appel avec plusieurs arguments au lieu d'un tableau) un nouveau tableau créé par le compilateur en interne que vous pouvez utiliser en toute sécurité, c'est certainement un comportement inattendu.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.