10.1 Générique introduction

Cliquez içi pour plus de vidéos disponibles sur notre chaine youtube !

Les génériques permettent d'écrire des classes et des méthodes qui fonctionnent avec différents types de données sans sacrifier la sécurité de typage. Introduits dans Java 5, ils sont au cœur de l'API des collections : vous les avez déjà rencontrés en utilisant ArrayList<String> ou LinkedList<Integer>.

Le problème que les génériques résolvent

Imaginons une classe Boite destinée à contenir une valeur. Si on fige le type de cette valeur, par exemple en int, la classe ne pourra plus jamais contenir une chaîne de caractères. Si on le fige en String, l'inverse est vrai. Il faudrait dupliquer la classe pour chaque type — une mauvaise idée.

Le générique répond exactement à ce besoin : il laisse la classe travailler avec un type qui ne sera décidé qu'au moment de l'utilisation.

Déclarer une classe générique

On déclare un paramètre de type entre chevrons < > juste après le nom de la classe. Ce paramètre, traditionnellement nommé T (pour Type), représente un type quelconque que l'on peut ensuite utiliser dans toute la classe :

public class Boite<T> {
    private T contenu;

    public void setContenu(T contenu) {
        this.contenu = contenu;
    }

    public T getContenu() {
        return contenu;
    }
}

À l'utilisation, on précise le type réel entre chevrons. Le compilateur connaît alors le type exact et vérifie la cohérence du code :

Boite<Integer> boiteNombre = new Boite<>();
boiteNombre.setContenu(12);          // OK
int age = boiteNombre.getContenu();  // pas de cast nécessaire

Boite<String> boiteTexte = new Boite<>();
boiteTexte.setContenu("Bonjour");    // OK
// boiteTexte.setContenu(12);        // erreur de compilation

Points clés à retenir

  • Le paramètre de type est par convention une seule lettre majuscule : T pour un type, E pour un élément, K et V pour une clé et une valeur.
  • Un paramètre de type ne peut être qu'une classe, jamais un type primitif. On écrit donc Boite<Integer> et non Boite<int> — on utilise les classes enveloppes (Integer, Double, etc.).
  • Les erreurs de type sont détectées dès la compilation, ce qui évite les ClassCastException à l'exécution.

Les leçons suivantes approfondissent les génériques avec les méthodes génériques et les paramètres de type multiples.