Génériques et collections typées en programmation objet
Informatique de gestion · Bachelor 3
Types paramétrés, bornes, invariance et collections sûres : écrire du code réutilisable et typé.
Introduction
Les génériques permettent d'écrire une classe ou une méthode une seule fois pour plusieurs types, tout en gardant la vérification de types à la compilation. Une List<Client> ne peut contenir que des clients : le compilateur refuse l'ajout d'une facture et supprime les conversions explicites risquées qui provoquaient des erreurs à l'exécution dans les premières versions de Java.
Au-delà des collections de la bibliothèque standard, on définit ses propres types paramétrés, par exemple un Repository<T> réutilisable pour toutes les entités d'une application de gestion, ou une méthode générique de tri. On peut restreindre le paramètre par une borne (T extends Comparable<T>) afin de pouvoir utiliser les opérations de la borne.
Les génériques introduisent aussi des subtilités : List<Client> n'est pas une List<Personne> même si Client hérite de Personne (invariance), ce qui motive les jokers. En Java, l'effacement de type supprime l'information de type à l'exécution, alors que C# la conserve.
Objectifs d'apprentissage
- Définir une classe et une méthode génériques avec un ou plusieurs paramètres de type
- Utiliser une borne pour exiger une capacité (comparabilité) sur le paramètre
- Expliquer pourquoi List<Client> n'est pas un sous-type de List<Personne>
- Choisir entre jokers extends et super selon qu'on lit ou qu'on écrit
- Citer les limites des génériques liées à l'effacement de type en Java
Concepts clés
- Type paramétré
- Classe ou interface déclarée avec un paramètre de type (Boite<T>) instancié lors de l'utilisation (Boite<Facture>).
- Borne
- Contrainte sur le paramètre (T extends Comparable<T>) qui autorise l'usage des méthodes de la borne dans le code générique.
- Invariance et jokers
- Les types paramétrés sont invariants ; les jokers (? extends T pour lire, ? super T pour écrire) expriment une covariance ou contravariance contrôlée.
- Effacement de type
- En Java, les paramètres de type sont supprimés à la compilation : on ne peut pas faire new T() ni instanceof List<String>.
Conclusion
Les génériques sont l'outil qui permet de réutiliser sans sacrifier la sûreté de typage. Maîtriser les bornes et les jokers évite autant de copier-coller que d'erreurs de conversion à l'exécution.
Dans un projet de gestion, ils servent chaque jour : collections typées, dépôts de données génériques, utilitaires de tri. Comprendre l'invariance et l'effacement de type évite les surprises lors de la conception d'API réutilisables.
Cartes
- Quel problème les génériques résolvent-ils ?
- Ils offrent la réutilisation du code pour plusieurs types avec vérification statique, sans conversions explicites dangereuses.
- Que signifie List<Client> ?
- Une liste dont tous les éléments sont de type Client, ce que le compilateur vérifie.
- Comment écrire une méthode générique qui retourne le maximum d'une liste ?
- En déclarant un paramètre de type borné par Comparable : <T extends Comparable<T>> T max(List<T> liste).
- Pourquoi List<Client> n'est-elle pas une List<Personne> ?
- Si c'était permis, on pourrait y ajouter une Personne non Client : l'invariance protège contre cette violation de type.
- Quand utiliser ? extends T ?
- Quand on ne fait que lire dans la structure (producteur) : on obtient des T mais on ne peut pas y ajouter d'éléments.
- Quand utiliser ? super T ?
- Quand on ne fait qu'écrire dans la structure (consommateur) : on peut y ajouter des T mais on lit seulement des Object.
- Que provoque l'effacement de type en Java ?
- Les paramètres de type n'existent plus à l'exécution : pas de new T(), pas de tableau de T, pas de instanceof avec un type paramétré.
- Pourquoi préférer Map<String, Facture> à Map brute ?
- Le type brut désactive les contrôles et réintroduit les erreurs de conversion à l'exécution.
- Quel est l'intérêt d'un Repository<T> générique ?
- Écrire une seule fois les opérations de persistance communes (trouver, enregistrer, supprimer) pour toutes les entités.
Glossaire
- Paramètre de type
- Variable de type déclarée entre chevrons qui sera remplacée par un type concret.
- Borne supérieure
- Contrainte qui impose au paramètre d'être un sous-type d'un type donné.
- Joker (wildcard)
- Notation ? représentant un type inconnu dans un type paramétré.
- Invariance
- Propriété selon laquelle G<A> et G<B> sont sans lien de sous-typage même si A hérite de B.
- Effacement de type
- Suppression des informations de type paramétré lors de la compilation Java.
- Type brut (raw type)
- Utilisation d'une classe générique sans paramètre de type, qui désactive les vérifications.