logo

Genèrics en Java

Genèrics significa tipus parametritzats . La idea és permetre que el tipus (Enter, String, ... etc., i tipus definits per l'usuari) sigui un paràmetre per a mètodes, classes i interfícies. Amb Genèrics, és possible crear classes que funcionin amb diferents tipus de dades. Una entitat com una classe, una interfície o un mètode que opera amb un tipus parametritzat és una entitat genèrica.

Per què genèrics?

El Objecte és la superclasse de totes les altres classes i la referència a l'objecte pot fer referència a qualsevol objecte. Aquestes característiques manquen de seguretat tipus. Els genèrics afegeixen aquest tipus de funció de seguretat. Analitzarem aquest tipus de funció de seguretat en exemples posteriors.



Els genèrics en Java són similars a les plantilles en C++. Per exemple, classes com HashSet, ArrayList, HashMap, etc., utilitzen molt bé els genèrics. Hi ha algunes diferències fonamentals entre els dos enfocaments dels tipus genèrics.

Tipus de genèrics Java

Mètode genèric: El mètode genèric Java pren un paràmetre i retorna algun valor després de realitzar una tasca. És exactament com una funció normal, però, un mètode genèric té paràmetres de tipus que es citen pel tipus real. Això permet utilitzar el mètode genèric d'una manera més general. El compilador té cura del tipus de seguretat que permet als programadors codificar fàcilment, ja que no han de realitzar càstings llargs i individuals.

Classes genèriques: Una classe genèrica s'implementa exactament com una classe no genèrica. L'única diferència és que conté una secció de paràmetres de tipus. Hi pot haver més d'un tipus de paràmetre, separats per coma. Les classes, que accepten un o més paràmetres, es coneixen com a classes parametritzades o tipus parametritzats.



Classe genèrica

Igual que C++, utilitzem per especificar tipus de paràmetres en la creació de classes genèriques. Per crear objectes d'una classe genèrica, utilitzem la sintaxi següent.

// To create an instance of generic class BaseType obj = new BaseType ()>

Nota: En el tipus de paràmetre no podem utilitzar primitives com 'int', 'char' o 'double'.

Java






// Java program to show working of user defined> // Generic classes> // We use to specify Parameter type> class> Test {> >// An object of type T is declared> >T obj;> >Test(T obj) {>this>.obj = obj; }>// constructor> >public> T getObject() {>return> this>.obj; }> }> // Driver class to test above> class> Main {> >public> static> void> main(String[] args)> >{> >// instance of Integer type> >Test iObj =>new> Test(>15>);> >System.out.println(iObj.getObject());> >// instance of String type> >Test sObj> >=>new> Test(>'GeeksForGeeks'>);> >System.out.println(sObj.getObject());> >}> }>

>

>

Sortida

15 GeeksForGeeks>

També podem passar diversos paràmetres de tipus a les classes genèriques.

Java

powershell major o igual




// Java program to show multiple> // type parameters in Java Generics> // We use to specify Parameter type> class> Test> {> >T obj1;>// An object of type T> >U obj2;>// An object of type U> >// constructor> >Test(T obj1, U obj2)> >{> >this>.obj1 = obj1;> >this>.obj2 = obj2;> >}> >// To print objects of T and U> >public> void> print()> >{> >System.out.println(obj1);> >System.out.println(obj2);> >}> }> // Driver class to test above> class> Main> {> >public> static> void> main (String[] args)> >{> >Test obj => >new> Test(>'GfG'>,>15>);> >obj.print();> >}> }>

>

>

Sortida

GfG 15>

Funcions genèriques:

També podem escriure funcions genèriques que es poden cridar amb diferents tipus d'arguments en funció del tipus d'arguments passats al mètode genèric. El compilador gestiona cada mètode.

Java




java convertir char a int

// Java program to show working of user defined> // Generic functions> class> Test {> >// A Generic method example> >static> >void> genericDisplay(T element)> >{> >System.out.println(element.getClass().getName()> >+>' = '> + element);> >}> >// Driver method> >public> static> void> main(String[] args)> >{> >// Calling generic method with Integer argument> >genericDisplay(>11>);> >// Calling generic method with String argument> >genericDisplay(>'GeeksForGeeks'>);> >// Calling generic method with double argument> >genericDisplay(>1.0>);> >}> }>

>

>

Sortida

java.lang.Integer = 11 java.lang.String = GeeksForGeeks java.lang.Double = 1.0>

Els genèrics només funcionen amb tipus de referència:

Quan declarem una instància d'un tipus genèric, l'argument de tipus passat al paràmetre de tipus ha de ser un tipus de referència. No podem utilitzar tipus de dades primitius com int , char.

Test obj = new Test(20);>

La línia anterior produeix un error en temps de compilació que es pot resoldre mitjançant embolcalls de tipus per encapsular un tipus primitiu.

Però les matrius de tipus primitiu es poden passar al paràmetre de tipus perquè les matrius són tipus de referència.

ArrayList a = new ArrayList();>

Els tipus genèrics es diferencien segons els seus arguments de tipus:

Considereu el següent codi Java.

Java




// Java program to show working> // of user-defined Generic classes> // We use to specify Parameter type> class> Test {> >// An object of type T is declared> >T obj;> >Test(T obj) {>this>.obj = obj; }>// constructor> >public> T getObject() {>return> this>.obj; }> }> // Driver class to test above> class> Main {> >public> static> void> main(String[] args)> >{> >// instance of Integer type> >Test iObj =>new> Test(>15>);> >System.out.println(iObj.getObject());> >// instance of String type> >Test sObj> >=>new> Test(>'GeeksForGeeks'>);> >System.out.println(sObj.getObject());> >iObj = sObj;>// This results an error> >}> }>

>

>

Sortida:

error: incompatible types: Test cannot be converted to Test>

Tot i que iObj i sObj són de tipus Test, són les referències a diferents tipus perquè els seus paràmetres de tipus difereixen. Els genèrics afegeixen seguretat de tipus a través d'això i eviten errors.

Paràmetres de tipus a Java Generics

Les convencions de denominació dels paràmetres de tipus són importants per aprendre genèrics a fons. Els paràmetres de tipus comuns són els següents:

hashtable java
  • T - Tipus
  • E – Element
  • K – Clau
  • N – Número
  • V – Valor

Avantatges dels genèrics:

Els programes que utilitzen genèrics tenen molts avantatges respecte al codi no genèric.

1. Reutilització del codi: Podem escriure un mètode/classe/interfície una vegada i utilitzar-lo per a qualsevol tipus que vulguem.

2. Tipus de seguretat: Els genèrics cometen errors per aparèixer en temps de compilació que en temps d'execució (sempre és millor conèixer els problemes del codi en temps de compilació en lloc de fer que el codi falli en temps d'execució). Suposem que voleu crear una ArrayList que emmagatzemi el nom dels estudiants, i si per error el programador afegeix un objecte enter en lloc d'una cadena, el compilador ho permet. Però, quan recuperem aquestes dades de ArrayList, es produeixen problemes en temps d'execució.

Java




// Java program to demonstrate that NOT using> // generics can cause run time exceptions> import> java.util.*;> class> Test> {> >public> static> void> main(String[] args)> >{> >// Creatinga an ArrayList without any type specified> >ArrayList al =>new> ArrayList();> >al.add(>'Sachin'>);> >al.add(>'Rahul'>);> >al.add(>10>);>// Compiler allows this> >String s1 = (String)al.get(>0>);> >String s2 = (String)al.get(>1>);> >// Causes Runtime Exception> >String s3 = (String)al.get(>2>);> >}> }>

>

>

Sortida:

Exception in thread 'main' java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at Test.main(Test.java:19)>

Com resolen els genèrics aquest problema?

En definir ArrayList, podem especificar que aquesta llista només pot prendre objectes String.

Java




// Using Java Generics converts run time exceptions into> // compile time exception.> import> java.util.*;> class> Test> {> >public> static> void> main(String[] args)> >{> >// Creating a an ArrayList with String specified> >ArrayList al =>new> ArrayList ();> >al.add(>'Sachin'>);> >al.add(>'Rahul'>);> >// Now Compiler doesn't allow this> >al.add(>10>);> >String s1 = (String)al.get(>0>);> >String s2 = (String)al.get(>1>);> >String s3 = (String)al.get(>2>);> >}> }>

tutorial de java
>

>

Sortida:

15: error: no suitable method found for add(int) al.add(10); ^>

3. No cal un càsting de tipus individual: Si no fem servir genèrics, aleshores, a l'exemple anterior, cada vegada que recuperem dades de ArrayList, les haurem d'enregistrar. La tipografia en cada operació de recuperació és un gran maldecap. Si ja sabem que la nostra llista només conté dades de cadena, no caldrà escriure-les cada vegada.

Java




// We don't need to typecast individual members of ArrayList> import> java.util.*;> class> Test {> >public> static> void> main(String[] args)> >{> >// Creating a an ArrayList with String specified> >ArrayList al =>new> ArrayList();> >al.add(>'Sachin'>);> >al.add(>'Rahul'>);> >// Typecasting is not needed> >String s1 = al.get(>0>);> >String s2 = al.get(>1>);> >}> }>

>

>

4. Els genèrics promouen la reutilització del codi: Amb l'ajuda de genèrics en Java, podem escriure codi que funcionarà amb diferents tipus de dades. Per exemple,

Suposem que volem ordenar els elements de la matriu de diversos tipus de dades com int, char, String, etc.

Bàsicament necessitarem diferents funcions per a diferents tipus de dades.

Per simplificar, utilitzarem l'ordenació de bombolles.

Però utilitzant genèrics, podem aconseguir la funció de reutilització del codi.

Java




public> class> GFG {> >public> static> void> main(String[] args)> >{> >Integer[] a = {>100>,>22>,>58>,>41>,>6>,>50> };> >Character[] c = {>'v'>,>'g'>,>'a'>,>'c'>,>'x'>,>'d'>,>'t'> };> >String[] s = {>'Virat'>,>'Rohit'>,>'Abhinay'>,>'Chandu'>,>'Sam'>,>'Bharat'>,>'Kalam'> };> >System.out.print(>'Sorted Integer array : '>);> >sort_generics(a);> >System.out.print(>'Sorted Character array : '>);> >sort_generics(c);> >System.out.print(>'Sorted String array : '>);> >sort_generics(s);> > >}> >public> static> extends Comparable>void sort_generics(T[] a) { //A mesura que estem comparant els tipus de dades no primitius //hem d'utilitzar la classe comparable //Bubble Sort logic for (int i = 0; i 1; i++) { for (int j = 0; j 1; j++) { if (a[j].compareTo(a[j + 1])> 0) { swap(j, j + 1, a); } } } // Imprimeix els elements després d'ordenar per (T i : a) { System.out.print(i + ', '); } System.out.println(); } intercanvi de buit estàtic públic (int i, int j, T[] a) { T t = a[i]; a[i] = a[j]; a[j] = t; } }>>>

> 

nbsp
Mitjançant l'ús de genèrics, podem implementar algorismes que funcionen en diferents tipus d'objectes i, al mateix temps, també són segurs.