Vous êtes sur la page 1sur 10

Université de Ségou

Institut Universitaire de Formation Professionnelle


Année : 2019-2020

Cours de Java avancé :


Généricité avec Java
Dr Demba COULIBALY, Maître – Assistant
Plan du cours
1. Présentation
2. Problématique
3. Principes de la généricité en Java
4. Limites de la généricité
5. Utilisation de la généricité avec les Collections

Bibliographie
1. KOOR, Ressources Pédagogiques pour Développeurs,
https://koor.fr/Java/Tutorial/java_generics_introduction.wp, 07/07/2020
2. Maria Gradinariu, Java – 6 – Généricité et Collection,
https://pagesperso.lip6.fr/Maria.Gradinariu/IMG/html/c6-genericite-et-
collections.html, 10/07/2020
3. Cyrille Herby, Appréhendez la généricité en Java,
https://openclassrooms.com/fr/courses/26832-apprenez-a-programmer-en-
java/22404-apprehendez-la-genericite-en-java, 01/06/2019
4. Richard Grin, Généricité, Université de Nice - Sophia Antipolis, notes de cours.
5. https://fr.wikipedia.org/wiki/Généricité, 01/06/2019
6. Frédéric Gava, Introduction à la Programmation Java : généricité, le polymorphisme
paramétrique, L.A.C.L Laboratoire d’Algorithmique, Complexité et Logique, Cours de
L3 MIAGE, 01/06/2019
7. Michel Schinz, Collections et généricité, Pratique de la programmation orientée-objet
https://cs108.epfl.ch/archive/14/files/ppo14_03_collections_listes_genericite.pdf,
11/07/2020

1. Présentation
En Programmation Orientée Object (POO), la généricité est un concept permettant de
définir des algorithmes (types de données et méthodes) identiques qui peuvent être
utilisés sur de multiples types de données. Cela permet donc de réduire les quantités de
codes à produire.

2. Problématique

a) Prenons l'exemple d'une classe SingleValueString qui possède :


 un constructeur SingleValueString(String value)
 une méthode (modificateur) setValue(String value)
 une méthode (accesseur) String getValue()
Cette classe permet de stocker une valeur de type String.

package genericite;

public class SingleValueString {


private String value;
public SingleValueString() {}
public SingleValueString(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

Cette classe peut être utilisée comme suite :

SingleValueString svs = new SingleValueString("Ségou");


System.out.println(svs.getValue());

b) Si on veut pouvoir stocker un entier, on peut créer une classe SingleValueInt avec :
 un constructeur SingleValueInt(int val)
 une méthode (modificateur) setValue(int val)
 une méthode (accesseur) int getValue()

package genericite;

public class SingleValueInt {


private int value;
public SingleValueInt() {}
public SingleValueInt(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}

Cette classe peut être utilisée comme suite :


SingleValueInt svi = new SingleValueInt(42);
int c = svi.getValue() + 1;
System.out.println(c);
c) Si on veut pouvoir stocker une personne, on peut créer une classe
SingleValuePerson avec :
 un constructeur SingleValuePerson(Person val)
 une méthode (modificateur) setValue(Person val)
 une méthode (accesseur) Person getValue()

package genericite; package genericite;

public class Person { public class SingleValuePerson {


private String name; private Person value;
private int age; public SingleValuePerson() {}
public Person() {} public SingleValuePerson(Person
public Person(String name) { value) {
this.name = name; this.value = value;
} }
public String getName() { public Person getValue() {
return name; return value;
} }
public void setName(String name) { public void setValue(Person
this.name = name; value) {
} this.value = value;
public int getAge() { }
return age; }
}
public void setAge(int age) {
this.age = age;
}
}

SingleValuePerson svp = new SingleValuePerson(new


Person("alice"));
svp.getValue().setAge(39);
System.out.println(svp);

Constat : Les trois classes SingleValueString, SingleValueInt et


SingleValuePerson ont des structures semblables et peuvent être unifiées sous une
classe unique. Avant Java 5, le problème était résolu par le transtypage ou cast en anglais. La
classe unifiant ces trois objets peut avoir la forme suivante :
package genericite;

public class SingleValueObject {


private Object value;
public SingleValueObject() {}
public SingleValueObject(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}

1 package genericite;
2 public class ApplicationProblematique {
3
4 public static void main(String[] args) {
5 SingleValueObject svs=new SingleValueObject(new String("Ségou"));
6 System.out.println(svs.getValue());
7
8 SingleValueObject svp=new SingleValueObject(new
Person("COULIBALY"));
9 ((Person)svp.getValue()).setAge(25);
10 Person p=(Person)svp.getValue();
11 System.out.println(p.getName()+" a "+ p.getAge()+" ans");
12
13 SingleValueObject svi=new SingleValueObject(new Integer(45));
14 System.out.println((int)svi.getValue()+10);
15 }
16 }

Dans le code ci-dessus, vous pouvez constater sur les lignes n° 5, 9, 10 et 13 que pour obtenir
des objets ayant les types des trois précédents objets, nous créé respectivement sur les lignes
5 et 13 des objets de type String et Integer.
Sur les lignes 9 et 10 nous avons placé entre parenthèses la classe Person pour transformer
la valeur obtenue suite à l’invocation de la méthode getValue(). Cela est appelée
transtypage ou cast, car elle transforme la valeur retournée par la méthode en type Person.

Constat : avec cette solution, nous devons toujours faire recours au transtypage pour générer
des types concrets à partir d’un objet commun (brut).
Java 5 met à notre disposition, un moyen plus simple pour gérer de tels problèmes. C’est la
généricité.

3. Principe de la généricité en Java :


La généricité permet de créer une classe permettant de stocker des types quelconques sans
avoir une classe différente par type.
La généricité permet de paramétrer une classe ou une interface avec un ou plusieurs types
quelconques de données.
Java propose d'utiliser un type générique T qui sert à représenter un type d'objet quelconque.
La généricité n’existe qu’à la compilation.
Le code des classes qui instancient une même déclaration générique est unique à l’exécution.
Les variables de type n’existent plus à l’exécution.
Ainsi, la classe SingleValueObject devient SingleValue <T> :

package genericite;

public class SingleValue<T> {


//Variable d'instance
private T valeur;
//Constructeur par défaut
public SingleValue(){
this.valeur = null;
}
//Constructeur avec paramètre inconnu pour l'instant
public SingleValue(T val){
this.valeur = val;
}
//Définit la valeur avec le paramètre
public void setValue(T val){
this.valeur = val;
}
//Retourne la valeur déjà « castée » par la signature de la méthode !
public T getValue(){
return this.valeur;
}
}

Utilisation dans une application Java.


Exemple avec deux paramètres T et S
package genericite;

public class SingleValue<T, S> {


//Variable d'instance
private T valeur1;
private S valeur2
//Constructeur par défaut
public SingleValue(){
this.valeur1 = null;
this.valeur2 = null;
}
//Constructeur avec paramètre inconnu pour l'instant
public SingleValue(T val){
this.valeur = val;
}
//Définit la valeur avec le paramètre
public void setValue(T val){
this.valeur = val;
}
//Retourne la valeur déjà « castée » par la signature de la méthode !
public T getValue(){
return this.valeur;
}
}

package genericite;

public class Application {

public static void main(String[] args) {


SingleValue<Person> svp1 = new SingleValue<Person>(new
Person("Ngoï Tomassa"));
svp1.getValue().setAge(39);
System.out.println(svp1.getValue().getName());
System.out.println(svp1.getValue().getAge());

System.out.println("=====================================");

SingleValue<Person> svp2 = new SingleValue(new


Person("Sébougou Kanoubabnouma"));
svp2.getValue().setAge(39);
System.out.println(svp2.getValue().getName());
System.out.println(svp2.getValue().getAge());

System.out.println("======================================");

SingleValue<Integer> svi = new SingleValue<Integer>(45);


int c = 1 + svi.getValue();
System.out.println(svi.getValue());
}

}
4. Limitations de la généricité
Pour des raisons historiques, la généricité en Java possède les limitations suivantes :
 la création de tableaux dont les éléments ont un type générique est interdite,
 les tests d'instance impliquant des types génériques sont interdits,
 les transtypages (casts) sur des types génériques ne sont pas sûrs, c’est à dire qu'ils
produisent un avertissement lors de la compilation et un résultat éventuellement
incorrect à l'exécution,
 la définition d'exceptions génériques est interdite.

5. Utilisation de la généricité avec les Collections


L’API Java fournit un certain nombre de collections dans le Java collections framework.
Tout son contenu se trouve dans le package java.util.
Pour chaque collection, il existe :
 une interface,
 une ou plusieurs mises en œuvre, sous la forme de classes.

Les listes (List<E>), les ensembles (Set<E>), les piles (Stack<E>), les files d’attente
(Queue<E>) sont des objets qui regroupent plusieurs éléments en une seule entité.
 en commun :
o mêmes questions : est-ce qu’elles contiennent des éléments ? combien ?
o mêmes opérations : on peut ajouter ou enlever un élément à la structure,
on peut vider la structure. On peut aussi parcourir les éléments contenus
dans la structure.
 implémentations différentes
Collection<E> : méthodes de base pour parcourir, ajouter, enlever des éléments.
Set<E> : cette interface représente un ensemble, et donc, ce type de collection n’admet
aucun doublon.
List<E> : cette interface représente une séquence d’éléments : l’ordre d’ajout ou de
retrait des éléments est important (doublons possibles).
Queue<E> : file d’attente : il y a l’élément en tête et il y a les éléments qui suivent.
L’ordre d’ajout ou de retrait des éléments est important (doublons possibles).
Deque<E> : cette interface ressemble aux files d’attente, mais les éléments importants
sont les éléments en tête et en queue.
Map<K,V> : cette interface représente une relation binaire (surjective) : chaque élément
est associé à une clé et chaque clé est unique (mais on peut avoir des doublons pour les
éléments).
SortedSet<E> : est la version ordonnée d’un ensemble.
SortedMap<K,V> : est la version ordonnée d’une relation binaire ou les clés sont
ordonnées.
ArrayList<E> : stocke les éléments dans un tableau qui est « redimensionné » par
copie au besoin. C’est une classe qui implémente l’interface List<E>.
LinkedList<E> : stocke les éléments dans des nœuds chaînés entre eux.

Ces interfaces sont génériques, c’est-à-dire on peut leur donner un paramètre pour
indiquer qu’on a une collection de Person, de Integer, de String, etc...
Exemple :

package genericite;

public class PN {
private String phonenumber;

public PN() {}
public PN(String phonenumber) {
this.phonenumber = phonenumber;
}
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
}
package genericite;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GenericiteCollection {

public static void main(String[] args) {


List<String> workingDays = new ArrayList<>();
workingDays.add("lundi");
workingDays.add("mardi");
workingDays.add("mercredi");
workingDays.add("jeudi");
workingDays.add("vendredi");
System.out.println("nb. de jours ouvrés : " + workingDays.size());
System.out.println("2e jour ouvré : " + workingDays.get(1));

System.out.println("=====================================================
==");

Map<String, PN> pBook = new HashMap<>();


pBook.put("Jean", new PN("078 123 45 69"));
pBook.put("Marie", new PN("079 157 78 89"));// ...
pBook.put("Ursule",new PN("026 688 87 98"));
System.out.println("Le numéro de Jean est "+
pBook.get("Jean").getPhonenumber());
pBook.put("Marie", new PN("077 554 12 55"));
pBook.remove("Ursule");

System.out.println("=====================================================
==");
System.out.println("Les éléments sont :" + pBook);
}

Vous aimerez peut-être aussi