« Salut Amigo ! »

« Salut, Élie ! »

"Aujourd'hui, Rishi et moi allons tout vous dire sur les génériques."

"Attendez, je pense que je sais déjà presque tout."

« Presque tout, mais pas tout.

« Vraiment ? OK, je suis prêt à écouter.

"Alors commençons."

"En Java, les génériques sont des classes qui ont des paramètres de type."

"Pour savoir pourquoi les génériques ont été inventés, voir les commentaires dans le code :"

Exemple
ArrayList stringList = new ArrayList();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // Add a number to the list

for(Object o: stringList)
{
 String s = (String) o; // There will be an exception here when we get to the integer
}

Comment résoudre le problème en utilisant les génériques :

Exemple
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // There will be a compilation error here

for(Object o: stringList)
{
 String s = (String) o;
}

"Ce code ne se compile tout simplement pas et l'erreur causée par l'ajout du mauvais type de données sera remarquée lors de la compilation."

"Oui, je le sais déjà."

"D'accord, bien. La répétition est la mère de l'apprentissage."

"Mais les créateurs de Java étaient un peu paresseux lorsqu'ils ont créé des génériques. Au lieu de créer des types à part entière avec des paramètres, ils ont glissé dans une optimisation astucieuse. En réalité, ils n'ont ajouté aucune information sur les paramètres de type aux génériques. Au lieu de cela, tous les la magie se produit pendant la compilation."

Coder avec des génériques
List<String> strings = new ArrayList<String>();
strings.add("abc");
strings.add("abc");
strings.add( 1); // Compilation error

for(String s: strings)
{
 System.out.println(s);
}
Que se passe-t-il vraiment
List strings = new ArrayList();

strings.add((String)"abc");
strings.add((String)"abc");
strings.add((String) 1); // Compilation error

for(String s: strings)
{
 System.out.println(s);
}

"C'est lisse."

"Oui, mais cette approche a un effet secondaire.  Aucune information sur les paramètres de type n'est stockée dans une classe générique.  Cette approche est devenue plus tard connue sous le nom d'effacement de type ."

"En d'autres termes, si vous avez votre propre classe avec des paramètres de type, vous ne pouvez pas utiliser d'informations à leur sujet à l'intérieur de la classe."

Coder avec des génériques
class Zoo<T>
{
 ArrayList<T> pets = new ArrayList<T>();

 public T createAnimal()
 {
  T animal = new T();
  pets.add(animal)
  return animal;
 }
}
Que se passe-t-il vraiment
class Zoo
{
 ArrayList pets = new ArrayList();

 public Object createAnimal()
 {
  Object animal = new ???();
  pets.add(animal)
  return animal;
 }
}

"Lors de la compilation, tous les types de paramètres sont remplacés par Object. Et à l'intérieur de la classe, il n'y a aucune information sur le type qui lui est transmis."

"Oui, je suis d'accord, ce n'est pas le meilleur."

"Ce n'est pas si effrayant. Je te dirai plus tard comment contourner ce problème."

Mais il y a plus. Java vous permet de spécifier un type parent pour les paramètres de type. Le mot clé extend est utilisé pour cela. Par exemple:

Coder avec des génériques
class Zoo<T extends Cat>
{
 T cat;

 T getCat()
 {
  return cat;
 }

 void setCat (T cat)
 {
  this.cat = cat;
 }

 String getCatName()
 {
  return this.cat.getName();
 }
}
Que se passe-t-il vraiment
class Zoo
{
 Cat cat;

 Cat getCat()
 {
  return cat;
 }

 void setCat(Cat cat)
 {
  this.cat = cat;
 }

 String getCatName()
 {
  return this.cat.getName();
 }
}

"Notez deux faits :"

"Tout d'abord, vous ne pouvez pas passer n'importe quel type en tant que paramètre - vous ne pouvez passer qu'un Cat ou une classe qui hérite de Cat."

"Deuxièmement, à l'intérieur de la classe Zoo, les variables de type T peuvent désormais appeler les méthodes de la classe Cat.  La colonne de droite explique pourquoi (car Cat sera remplacé partout où il y a un T)"

"Oui. Si nous disons que Cat ou une sous-classe de Cat est passée comme argument de type, alors nous sommes certains que le type T aura toujours les méthodes de la classe Cat."

"Eh bien, c'est intelligent."