Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Java : les var-args

Les var-args (liste d’arguments variable) sont une nouveauté Java 5, qui rentre dans la catégorie des "syntaxic sugar".
Autrement dit, ce n’est pas indispensable, mais ça rend bien service.

Alors, à quoi ça sert ? Principalement à simplifier le passage de tableaux en paramètre des méthodes.
Voyons comment.

Un premier exemple

Prenons un exemple : afficher un ensemble de Strings.

  1. public void printAll(String[] strings) {
  2. for (String s : strings) {
  3. System.out.println(s);
  4. }
  5. }

Avec la méthode “historique”, il fallait construire un tableau pour passer les Strings en paramètre, comme ceci :

  1. String[] strings = new String[] {"foo", "bar"};
  2. printAll(strings);

ou constuire le tableau directement dans l’appel :

  1. printAll(new String[] {"foo", "bar"});

Les var-args permettent de simplifier cette écriture.
Il suffit de changer légèrement la signature de la méthode (notez les trois points "…" au lieu des crochets) :

  1. public void printAll(String... strings) {
  2. for(String s : strings) {
  3. System.out.println(s);
  4. }
  5. }

Le code d’appel est maintenant plus simple :

  1. printAll("foo", "bar");
  2. printAll("foo", "bar", "baz", "toto");

Un peu de théorie

On peut désormais passer un nombre variable d’arguments (pourvu qu’ils soient tous du type déclaré dans la signature de la méthode, évidemment), sans créer explicitement de tableau ! En revanche, dans le corps de la méthode, la variable var-arg est considéré comme un banal tableau et peut donc être parcourue par un « foreach », fournir sa taille avec la propriété length, etc.

Il y a toutefois deux petites limitations à cette syntaxe :

  • Il ne peut y avoir qu’un seul var-arg par signature de méthode
  • Le var-arg doit toujours être le dernier paramètre

En pratique, les var-args sont très pratiques pour les setters :

  1. public void setStrings(final String... strings) {
  2. this.strings = strings;
  3. }

Cette syntaxe peut rendre moins fastidieuse la construction de grappes d'objets reposant lourdement sur des tableaux, comme par exemple lors de l'écriture de mocks pour les tests unitaires. Je vous recommande donc de l’appliquer pour tous vos setters simples prenant des tableaux en paramètre.

En pratique

Combinés aux generics, les var-args permettent de créer des méthodes utilitaires puissantes, flexibles et simples d’utilisation.
Par exemple, voici une méthode permettant de construire une liste à partir des objets passés en paramètre.

  1. public static <T> List<T> toList(T... elements) {
  2. if (elements == null) {
  3. return Collections.<T> emptyList();
  4. }
  5. List<T> list = new ArrayList<T>();
  6. for (T element : elements) {
  7. list.add(element);
  8. }
  9. return list;
  10. }

Cette méthode est simple à utiliser :

  1. List<String> strings = Utils.toList("foo", "bar", "baz", "toto");

Commentaires

1. Le jeudi 24 juillet 2008, 10:48 par fabien29200

La méthode toList n'existe-t-elle pas déjà ... genre Arrays.asList() ;)

2. Le jeudi 24 juillet 2008, 11:25 par Olivier Croisier

Je connais bien la méthode Arrays.asList(). Son principal problème est que la liste qu'elle renvoie se base sur un tableau et est donc de taille fixe. On peut très bien l'utiliser si l'on est averti de cette limitation, mais dans le cas contraire, les effets de bord sont relativement difficiles à débugger (l'exception lancée en cas de dépassement de la capacité de la liste est une UnsupportedOperationException...). La méthode utilitaire que je présente comme exemple n'a pas cette limitation.

3. Le jeudi 24 juillet 2008, 12:22 par fabien29200

Je ne connaissais pas cette limitation, mais c'est aussi du au fait que je n'ai utilisé Arrays.asList() que pour créer des listes constantes (static final).

Vu la limitation dont tu parles, c'est peut-être juste pour cet usage qu'elle a été créée.

En tout cas, bravo pour ce blog sur lequel j'apprends quasiment à chaque post !

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.