Accueil > Non classé > La notation varargs en Java

La notation varargs en Java

Toujours dans le domaine du passage d’argument, voici un article présentant la notation varargs apparut dans J2SE 5.0.

Pour ceux qui ne connaissent pas varargs, je parie que vous vous êtes déjà retrouvé dans une situation où vous vouliez passer plusieurs arguments à une méthode, sans savoir leur nombre exact au moment de la compilation. Dans ce cas, vous utilisiez sûrement un tableau ou une structure de données comme ArrayList dans laquelle vous ajoutiez vos arguments. C’est parce que vous ne connaissiez pas vargars ! Varargs est une notation permettant de passer à une méthode ou à un constructeur un nombre variable d’arguments. On parle alors de fonctions variadiques.

Voici un exemple de l’utilisation de la notation varargs :

public static void main(String[] args)
{
    imprimeBonjour("Steve"); // imprime "1 Bonjour Steve"
    imprimeBonjour("Bill", "Bob"); // imprime "2 Bonjour Bill Bonjour Bob"

    String[] tab = {"Samuel", "John"};
    imprimeBonjour(tab); // imprime "2 Bonjour Samuel Bonjour John"
}

private static void imprimeBonjour(String... prenoms)
{
    System.out.print(prenoms.length + " ");
    for (String prenom : prenoms)
    {
        System.out.print("Bonjour " + prenom + " ");
    }
}

Comme vous pouvez le voir, il suffit juste de mettre 3 petits points après le type du dernier paramètre et la méthode peut alors être appelée avec n’importe quel nombre de paramètres, y compris zéro. L’exemple montre qu’il est également possible de passer un tableau à la méthode. Enfin vous remarquerez que “prenoms” est considéré par la méthode comme un tableau, et que l’on peut donc utiliser la notation “.length” et la boucle “foreach”.

Peut-être que certains d’entre vous se disent que varargs pourrait permettre d’éviter la surcharge de constructeurs. Imaginons que vous souhaitiez créer une API de géométrie :

public class Point
{
    int x, y;

    /**
    public Point()
    {
        this.x = 0; this.y = 0;
    }

    public Point(int x, int y)
    {
        this.x = x; this.y = y;
    }
    **/

    public Point (int... coordonnees) throws Exception
    {
        if(coordonnees.length == 0)
        {
            this.x = 0; this.y = 0;
        }
        else if (coordonnees.length == 2)
        {
            this.x = coordonnees[0]; this.y = coordonnees[1];
        }
        else
        {
            throw new Exception();
        }
    }
}

Plutôt que de proposer à vos futurs utilisateurs 2 constructeurs différents pour créer un objet Point, vous vous dites :
“Je vais leur simplifier la tâche en leur proposant un constructeur unique grâce à varargs“.

Je vous le dit tout de suite, ce n’est pas une bonne idée. C’est même une très mauvaise idée.
En effet, ça vous oblige à vérifier vous-même la taille du tableau passé en paramètre et à lancer une exception si le nombre d’arguments n’est pas valide. Si vous aviez utilisé la surchage de constructeur, lorsque vos utilisateurs auraient utilisé votre API, le compilateur se serait chargé de vérifier lui-même si le nombre de paramètres est correcte.
Bref, varargs vous force ici à écrire un code plus lourd et moins robuste.

  1. Pas encore de commentaire
  1. Pas encore de trackbacks