Qu'est-ce que les génériques en Java?

Les génériques en Java ont été introduits en 2004 en tant que nouvelle fonctionnalité du langage de programmation Java et faisaient partie de la version JDK 5. Il est le plus largement utilisé avec le cadre des collections Java. À ce jour, c'est l'une des fonctionnalités les plus importantes et les plus recherchées du langage de programmation Java.

Java générique a été trouvé par quatre personnes à savoir Gilad Bracha, Martin Odersky, David Stoutamire et Philip Wadler en 1998. C'était une extension du langage Java qui supportait les types génériques. Il visait à atteindre deux objectifs principaux qui sont:

  1. Type de sécurité
  2. Réutilisation du code

Définition des génériques en Java

Les génériques peuvent être définis comme un moyen de parvenir à la réutilisation du code en définissant des classes génériques, des interfaces, des constructeurs et des méthodes qui peuvent être utilisés avec différents types de données et également assurer la sécurité des types en déclarant le type de données utilisé dans l'implémentation au préalable, éliminant ainsi les chances d'une erreur d'exécution.

Comment les génériques sont-ils implémentés en Java?

Les génériques sont implémentés à l'aide de crochets angulaires «». Les crochets entourent le paramètre de type «T». Exemple, . Le paramètre de type «T» est un espace réservé qui indique qu'un type de données lui sera attribué au moment de l'exécution. Par exemple, une classe générique sera définie comme:

public class MyGenericClass (…)

Voici les paramètres de type standard:

  • T: Type
  • E: élément
  • N: nombre
  • K: Clé
  • V: valeur

S, U, V et ainsi de suite sont utilisés pour définir respectivement les deuxième, troisième et quatrième paramètres dans le cas où plusieurs paramètres sont utilisés.

Comprendre les génériques en Java

Vous vous demandez peut-être maintenant ce qu'est la sécurité de type et comment cela fonctionne-t-il? Ou en quoi les classes, interfaces, constructeurs et méthodes génériques sont-ils différents de nos classes et méthodes régulières qui les rendent réutilisables? Découvrons-le.

Java étant un langage à typage statique, vous devez déclarer le «type» qui est le type de données de la valeur détenue par la variable avant de l'utiliser.

Exemple: String myString =”eduCBA”;

Ici, "String" est le type de données, "myString" est la variable qui contiendra une valeur dont le type est String.

Maintenant, si vous essayez de passer une valeur booléenne à la place d'une chaîne, par exemple:

String myBooleanStr = true;

Vous obtiendrez immédiatement une erreur au moment de la compilation indiquant «Non-correspondance de type: impossible de convertir de booléen en chaîne».

Comment réaliser la réutilisation du code avec les génériques?

Maintenant, définissons une méthode régulière:

public static void welcome(String name)(
System.out.println("welcome to " + name);
)

Cette méthode ne peut être invoquée qu'en passant un paramètre de chaîne. Par exemple:

welcome(“eduCBA”);

Sa sortie sera «bienvenue à eduCBA».

Cependant, vous ne pouvez pas appeler cette méthode en contournant tout autre type de données tel que entier ou booléen. Si vous essayez de faire cela, vous serez invité avec une erreur de compilation indiquant «La méthode welcome (String) dans le type Runner n'est pas applicable pour les arguments (booléen)». Cela signifie que vous ne pouvez transmettre aucun autre type de données à une méthode qui accepte uniquement une chaîne comme paramètre.

Cela signifie également que si vous souhaitez invoquer une méthode similaire pour un type de données différent, vous devrez écrire une nouvelle méthode qui accepte le type de données requis comme paramètre. Cette fonctionnalité de réécriture de méthodes avec des paramètres de différents types de données est également connue sous le nom de surcharge de méthode. L'inconvénient majeur est qu'il augmente la taille de votre code.

Cependant, nous pourrions également utiliser des génériques pour réécrire la méthode ci-dessus et l'utiliser pour tout type de données dont nous avons besoin.

Définition d'une méthode générique:

public static void welcome(T t)(
System.out.println("it is " + t);
)

Remarque : Ici, «t» est un objet de type T. Le type de données utilisé pour invoquer la méthode sera attribué à T.

Vous pouvez maintenant réutiliser cette méthode en l'appelant pour une chaîne si nécessaire ou un booléen ou un entier ou tout autre type de données.

welcome("educate");
Integer Myint = 1;
welcome(Myint)
welcome(true);

Les instructions ci-dessus fourniront la sortie ci-dessous:

C'est Educa
C'est 1
C'est vrai

Par conséquent, en utilisant des génériques ici, nous sommes en mesure de réutiliser notre méthode pour différents types de données.

Comment assurer la sécurité des types à l'aide de génériques?

L'une des principales différences entre les tableaux et la collection est que les tableaux peuvent stocker uniquement des données homogènes, tandis que les collections peuvent stocker des données hétérogènes. Autrement dit, les collections peuvent stocker tout type / objet de données défini par l'utilisateur.

REMARQUE: les collections ne peuvent contenir que des objets (type de données défini par l'utilisateur) et non un type de données primitif. Afin de travailler avec des données primitives, les collections de types utilisent des classes wrapper.

Maintenant, considérons une ArrayList.

ArrayList myList = new ArrayList();

Ajoutons des données de type String, Integer et Double à l'objet ArrayList.

myList.add("eduCBA");
myList.add(1);
myList.add(5.2);

Lors de l'impression de l'objet ArrayList, nous pouvons voir qu'il contient les valeurs suivantes: (eduCBA, 1, 5.2).

Maintenant, si vous souhaitez récupérer ces valeurs dans des variables, vous devrez les transtyper.

String someStr = (String)myList.get(0);
Integer someInt = (Integer)myList.get(1);
Double someFlt = (Double)myList.get(2);

Dans le cas où vous n'avez pas transtypé, vous serez invité avec une erreur au moment de la compilation indiquant «Non-correspondance de type: impossible de convertir d'objet en chaîne».

À partir de cela, vous pouvez conclure que lors de la récupération des objets de votre ArrayList, vous devez le transtyper en leurs types respectifs. La question qui se pose ici est de savoir comment connaître le type de données dans lequel le transtyper? En temps réel, votre ArrayList contiendra des milliers d'enregistrements et le transtypage en différents types de données pour chaque objet individuel ne sera pas une option. Vous pourriez finir par le transtyper en un mauvais type de données. Que se passe-t-il alors?

Cette fois, vous n'obtiendrez pas d'erreur de compilation, mais vous générerez une erreur d'exécution indiquant «Exception dans le thread« principal »java.lang.ClassCastException: java.lang.Integer ne peut pas être converti en java.lang.String at com.serviceClasess.Runner .main (Runner.java:43) ».

Comme nous ne pouvons pas garantir le type de données présentes dans une collection (dans ce cas, ArrayList), elles ne sont pas considérées comme sûres à utiliser en ce qui concerne le type. C'est là que les génériques entrent en jeu pour assurer la sécurité du type.

Utilisation d'ArrayList avec des génériques:

ArrayList myList = new ArrayList();

Notez que dans les crochets angulaires «», le type String est spécifié, ce qui signifie que cette implémentation particulière d'ArrayList ne peut contenir que des données de type String. Si vous essayez d'y ajouter un autre type de données, cela générera simplement une erreur de temps de compilation. Ici, vous avez sécurisé votre type de tableau ArrayList en éliminant ses chances d'ajouter un type de données différent de «String».

Maintenant que vous avez spécifié le type de données qui peut être ajouté à votre collection à l'aide de génériques, vous n'avez plus besoin de le transtyper lors de la récupération de vos données. Autrement dit, vous pouvez simplement récupérer vos données en écrivant:

String someStr = myList.get(0);

Comment les génériques en Java facilitent-ils le travail?

Il aide à sécuriser le type de vos collections, garantissant ainsi que votre code n'échouera pas ultérieurement en raison d'une exception d'exécution. Cela évite également au codeur de devoir transtyper chaque objet de la collection, ce qui rend le développement du code plus rapide et plus facile. En utilisant des classes et des méthodes génériques, on peut également réutiliser le code selon le type de données requis lors de l'implémentation.

Que pouvez-vous faire d'autre avec les génériques en Java?

Jusqu'à présent, nous avons vu comment nous pouvons atteindre la sécurité des types et la réutilisation des codes avec les génériques. Voyons maintenant les autres fonctionnalités fournies par les génériques. Elles sont:

  1. Types délimités et délimités multiples
  2. Saisissez des caractères génériques

Type borné: dans le cas d'un type borné, le type de données d'un paramètre est lié à une plage particulière. Ceci est réalisé à l'aide du mot-clé «étend».

Par exemple, considérons une classe générique avec un paramètre de type borné qui étend l'interface Runnable:

class myGenericClass()

Maintenant, tout en créant son objet dans une autre classe:

myGenericClass myGen = new myGenericClass();

L'instruction ci-dessus s'exécutera parfaitement sans aucune erreur. C'est dans le cas du type borné, vous pouvez passer le même type de classe ou son type de classe enfant. En outre, vous pouvez lier le type de paramètre à une interface et passer ses implémentations lors de son appel, comme dans le cas de notre exemple ci-dessus.

Que se passe-t-il si vous essayez d'utiliser un autre type de paramètre?

myGenericClass myGen = new myGenericClass();

Dans le cas ci-dessus, vous obtiendrez une erreur au moment de la compilation indiquant «Non-concordance liée: le type Integer n'est pas un substitut valide pour le transtypage de type myGenericClass».

Types bornés multiples: dans le cas de plusieurs types bornés, nous pouvons lier le type de données de paramètre à plusieurs types. Par exemple,

Class myGeneric()

Dans ce cas, vous pouvez passer n'importe quel type qui étend la classe Number et implémente l'interface Runnable. Cependant, lors de l'utilisation de plusieurs types bornés, peu de choses doivent être notées:

  1. Nous ne pouvons pas prolonger plus d'une classe à la fois.
  2. Nous pouvons étendre n'importe quel nombre d'interfaces à la fois, c'est-à-dire qu'il n'y a pas de limite pour les interfaces.
  3. Le nom de la classe doit toujours venir en premier, suivi du nom de l'interface, sinon cela entraînera une erreur de compilation.

Caractères génériques de type: ils sont représentés par le symbole «?» - point d'interrogation. Il utilise deux mots clés principaux:

étend (pour définir la limite supérieure) et super (pour définir les limites inférieures).

Par exemple,

ArrayList al

Cet objet ArrayList «al» contiendra toutes les données de type T et toutes ses sous-classes.

ArrayList al

Cet objet ArrayList «al» contiendra toutes les données de type T et toutes ses superclasses.

Avantages des génériques en Java

1. Flexibilité : Generics offre à notre code la flexibilité de prendre en charge différents types de données à l'aide de classes et de méthodes génériques.

2. Maintenance et réutilisation du code : En raison des classes et méthodes génériques, il n'est pas nécessaire de réécrire le code, en cas de modification des exigences à un stade ultérieur, ce qui facilite la maintenance et la réutilisation du code.

3. Sécurité de type: fournit une sécurité de type au cadre de collecte en définissant le type de données que la collection peut contenir au préalable et en éliminant toute possibilité d'échec au moment de l'exécution en raison de ClassCastException.

4. Élimination de la nécessité de transtyper: Étant donné que les types de données détenus par les collections sont déjà déterminés, il n'est pas nécessaire de les transtyper au moment de la récupération. Cela réduit la longueur du code et réduit également l'effort d'un codeur.

Génériques dans les compétences Java

Pour travailler avec Generics, vous devez bien connaître les bases de Java. Vous devez comprendre comment fonctionne la vérification de type et la conversion de type. Une connaissance approfondie d'autres concepts tels que la surcharge de méthodes, la relation entre les classes parent et enfant, les interfaces et leurs implémentations est nécessaire. Il est également essentiel de comprendre la différence entre les types de données primitifs (type de données défini par le système) et les objets (type de données défini par l'utilisateur) lorsqu'il s'agit de travailler avec le cadre de collecte.

Pourquoi devrions-nous utiliser des génériques en Java?

L'utilisation de génériques rend notre code plus facile à gérer car elle réduit la nécessité de réécrire le code spécifique au type de données chaque fois qu'il y a un changement dans les exigences. En utilisant un type borné générique, vous pouvez restreindre le type de données et en même temps donner de la flexibilité à votre code en définissant sa plage. Votre code est moins susceptible d'échouer à un stade ultérieur car il offre une sécurité de type rendant votre code moins sujet aux erreurs.

Portée des génériques en Java

La portée des génériques est limitée au temps de compilation. Cela signifie que le concept générique n'est applicable qu'au moment de la compilation mais pas au moment de l'exécution. Par exemple,

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

Ici, les quatre déclarations ci-dessus sont une seule et même chose. Ils permettront l'ajout de tout type de données à l'objet liste.

Conclusion

Les génériques facilitent le codage pour un codeur. Il diminue les chances de rencontrer ClassCastException au moment de l'exécution en fournissant une vérification de type forte. Élimine complètement le besoin de transtypage de type, ce qui signifie que moins de code doit être écrit. Il nous offre la possibilité de développer des algorithmes génériques indépendants du type de données avec lequel ils travaillent.

Articles recommandés

Cela a été un guide sur Qu'est-ce que les génériques en Java?. Ici, nous avons discuté des compétences, de la portée, du travail, de la compréhension et des avantages des génériques en Java. Vous pouvez également consulter nos autres articles suggérés pour en savoir plus -

  1. Qu'est-ce que Common Gateway Interface
  2. Comment installer Java 8
  3. qu'est-ce que soapUI
  4. Qu'est-ce que JavaScript?
  5. Java booléens