Vous êtes sur la page 1sur 9

Généricité

Définition

Les génériques (de l'anglais generics) sont des classes qui sont typés au moment de la compilation.
Autrement dit, ce sont des classes qui utilisent des typages en paramètres. Ainsi une liste chainée, qui
peut contenir des entiers, des chaines ou autres, pourra être typée en liste de chaines ou liste d'entiers,
et ceci permettra au programmeur de ne pas écrire systématiquement des transtypages, méthode qui
pourrait s'avérer dangereuse, ce sera le compilateur qui vérifiera la cohérence des données.

Java 5 a introduit un principe de type générique, rappelant les templates (modèles) du C++, mais le
code produit est unique pour tous les objets obtenus à partir de la même classe générique.

Avant Java 5 :

Le transtypage est obligatoire, LinkedList manipule des objets Object, ici le compilateur ne peut
détecter de problème, problème qui ne surviendra qu'à l'exécution (RunTimeError).

Dans la version avec génériques, on n'a plus besoin d'utiliser le transtypage donc le compilateur
déclenchera deux erreurs durant la compilation, une sur la méthode, l'autre sur l'ajout d'un entier.
Utilisation :

Il est important de comprendre que dans la déclaration de la classe le paramètre placé entre les
caractères < et > représente bien une classe qui ne sera déterminée que lors de la déclaration de la
création de l'objet. Aussi une erreur de typage sera produite à la compilation si les types utilisés par les
méthodes ne sont le ou les types attendus. Dans cet exemple, l'erreur sera signalée sur le second ajout.

Dans la déclaration de la classe, la liste membre est déclarée ne pouvant contenir que des objets de
classe MaClasse. L'identifiant MaClasse n'est pas une classe existante dans le pa ckages et il est
préférable qu'il ne le soit pas pour qu'aucune confusion ne soit faite, c'est à la déclaration de l'objet
Famille que l'identifiant MaClasse sera résolu.

Il est évidemment possible d'utiliser un objet d'une classe héritant de celle utilisée pour paramétrer le
type générique. Ceci permet de plus d'assurer la compatibilité ascendante avec les versions antérieures
de Java : si aucune classe de paramétrage n'est indiquée, la classe par défaut est java.lang.Object.

Plusieurs paramètres

De la même façon que pour les classes basées sur les List, les déclarations de vos classes peuvent utiliser
ces génériques. Cela permet de rendre le code plus souple et surtout r éutilisable dans des contextes très
différents. Plusieurs paramètres, séparés par des virgules, peuvent être utilisés entre les caractères < et
>.
Déclaration possible :

ListeDeTruc<String,Integer> liste1 = new ListeDeTruc<String,Integer>();


ListeDeTruc<Thread,Date> liste2 = new ListeDeTruc<Thread,Date>();

Génériques et héritages

Lorsqu'un type de base doit répondre à des spécifications précises, il est possible d'écrire des choses du
genre :

En revanche, créer une classe qui hérite de ces objets est plus délicat. Ici Chose et Bidule sont des classes
existantes, Truc ne sera résolu qu'au moment de la déclaration de l'objet ListeDeTruc.

L'utilisation du mot clef super est possible dans une classe héritant d'une classe générique.

Tableau de génériques

La déclaration d'un tableau d'objets dont le type est générique peut se faire sans déclencher ni erreur,
ni avertissements et sans utiliser l'annotation @SuppressWarnings("unchecked"), en utilisant <?> :

Compatibilité entre les types

La relation d'héritage entre classe pour le type générique ne rend pas les classes compatibles.

La compatibilité est illustré ci-dessous, où la classe List hérite de la classe Collection et la classe Cat
hérite de la classe Animal :
Exemple :

class Animal { /* ... */ }


class Cat extends Animal { /* ... */ }

List<Cat> les_chats_du_voisinage = /* ... */;

List<? extends Cat> list_1 = les_chats_du_voisinage; // OK


Collection<Cat> list_2 = les_chats_du_voisinage; // OK
Collection<? extends Animal> list_3 = les_chats_du_voisinage; // OK

List<Animal> list_4 = les_chats_du_voisinage; // ERROR

Conventions sur les noms des types

Bien qu'il soit tout à fait possible d'utiliser n'importe-quel identifiant suivant la convention de
nommage des classes, il est plutôt recommandé d'utiliser un identifiant composé d'une seule lettre
selon la convention http://download.oracle.com/javase/tutorial/java/generic :

<E>
« Element », utilisé abondamment pour le type des éléments d'une collection ;
<K> et <V>
« Key » et « Value », pour respectivement le type des clés et celui des valeurs d'une Map ou
similaires ;
<N>
« Number » ;
<T>
« Type » ;
<S>, <U>, <V> etc.
second, troisième, i e type.

Limitations

Malgré la similitude de syntaxe, les types génériques en Java sont différents des patrons (templates en
anglais) du C++. Il faut plutôt les voir comme un moyen d'éviter de faire une conversion entre
java.lang.Object et le type spécifié de manière implicite.

Parmi les limitations :

il n'est pas possible d'implémenter plusieurs fois la même interface avec des paramètres
différents,
il n'est pas possible de créer deux versions surchargées d'une méthode (deux méthodes
portant le même nom) l'une utilisant la classe Object et l'autre utilisant un type générique.

Exemples

Exemple 1
Exemple2
Exemple3

Cas d’héritage
La dernière instruction sera soulignée en rouge car Véhicule n’hérite pas de la classe Personne