logo

Generici in Java

Generici significa tipi parametrici . L'idea è di consentire al tipo (Integer, String, ... ecc. e tipi definiti dall'utente) di essere un parametro per metodi, classi e interfacce. Utilizzando Generics, è possibile creare classi che funzionano con diversi tipi di dati. Un'entità come una classe, un'interfaccia o un metodo che opera su un tipo con parametri è un'entità generica.

Perché i generici?

IL Oggetto è la superclasse di tutte le altre classi e il riferimento all'oggetto può fare riferimento a qualsiasi oggetto. Queste funzionalità non dispongono dell'indipendenza dal tipo. I generici aggiungono questo tipo di funzionalità di sicurezza. Discuteremo questo tipo di funzionalità di sicurezza negli esempi successivi.



I generici in Java sono simili ai modelli in C++. Ad esempio, classi come HashSet, ArrayList, HashMap, ecc., utilizzano molto bene i generici. Esistono alcune differenze fondamentali tra i due approcci ai tipi generici.

Tipi di generici Java

Metodo generico: Il metodo Java generico accetta un parametro e restituisce un valore dopo aver eseguito un'attività. È esattamente come una funzione normale, tuttavia, un metodo generico ha parametri di tipo citati in base al tipo effettivo. Ciò consente di utilizzare il metodo generico in modo più generale. Il compilatore si occupa del tipo di sicurezza che consente ai programmatori di codificare facilmente poiché non devono eseguire lunghi casting individuali dei tipi.

Classi generiche: Una classe generica viene implementata esattamente come una classe non generica. L'unica differenza è che contiene una sezione di parametri di tipo. Possono esserci più tipi di parametri, separati da una virgola. Le classi, che accettano uno o più parametri, sono note come classi parametriche o tipi parametrizzati.



Classe generica

Come C++, usiamo per specificare i tipi di parametri nella creazione di classi generiche. Per creare oggetti di una classe generica, utilizziamo la seguente sintassi.

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

Nota: Nel tipo Parametro non possiamo usare primitive come 'int', 'char' o 'double'.

Giava






// 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());> >}> }>

>

>

Produzione

15 GeeksForGeeks>

Possiamo anche passare più parametri Type nelle classi generiche.

Giava

formato stringa in Java




// 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();> >}> }>

>

>

Produzione

GfG 15>

Funzioni generiche:

Possiamo anche scrivere funzioni generiche che possono essere chiamate con diversi tipi di argomenti in base al tipo di argomenti passati al metodo generico. Il compilatore gestisce ciascun metodo.

Giava




// 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>);> >}> }>

>

>

Produzione

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

I generici funzionano solo con i tipi di riferimento:

Quando dichiariamo un'istanza di un tipo generico, l'argomento tipo passato al parametro tipo deve essere un tipo di riferimento. Non possiamo usare tipi di dati primitivi come int , car.

stringa di suddivisione c++
Test obj = new Test(20);>

La riga precedente genera un errore in fase di compilazione che può essere risolto utilizzando wrapper di tipo per incapsulare un tipo primitivo.

Ma gli array di tipo primitivo possono essere passati al parametro type perché gli array sono tipi di riferimento.

ArrayList a = new ArrayList();>

I tipi generici differiscono in base agli argomenti relativi al tipo:

Considera il seguente codice Java.

Giava




// 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> >}> }>

>

>

Produzione:

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

Anche se iObj e sObj sono di tipo Test, sono riferimenti a tipi diversi perché i relativi parametri di tipo differiscono. I generici aggiungono l'indipendenza dai tipi attraverso questo e prevengono errori.

Digitare i parametri in Java Generics

Le convenzioni di denominazione dei parametri di tipo sono importanti per apprendere a fondo i generici. I parametri di tipo comuni sono i seguenti:

floppy disk
  • T – Tipo
  • E – Elemento
  • K – Chiave
  • N – Numero
  • V – Valore

Vantaggi dei generici:

I programmi che utilizzano Generics hanno molti vantaggi rispetto al codice non generico.

1. Riutilizzo del codice: Possiamo scrivere un metodo/classe/interfaccia una volta e utilizzarlo per qualsiasi tipo desideriamo.

2. Tipo di sicurezza: I generici fanno sì che gli errori vengano visualizzati in fase di compilazione piuttosto che in fase di esecuzione (è sempre meglio conoscere i problemi nel codice in fase di compilazione piuttosto che far fallire il codice in fase di esecuzione). Supponiamo di voler creare un ArrayList che memorizzi i nomi degli studenti e se per errore il programmatore aggiunge un oggetto intero invece di una stringa, il compilatore lo consente. Ma quando recuperiamo questi dati da ArrayList, causano problemi in fase di esecuzione.

Giava




// 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>);> >}> }>

>

>

Produzione :

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

In che modo i generici risolvono questo problema?

Quando definiamo ArrayList, possiamo specificare che questo elenco può accettare solo oggetti String.

Giava


tostring 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>);> >}> }>

>

>

Produzione:

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

3. Non è necessario il casting di tipo individuale: Se non utilizziamo i generici, quindi, nell'esempio precedente, ogni volta che recuperiamo dati da ArrayList, dobbiamo digitarli. Il typecasting ad ogni operazione di recupero è un grosso grattacapo. Se sappiamo già che la nostra lista contiene solo dati di tipo stringa, non abbiamo bisogno di digitarli ogni volta.

Giava




// 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. Generics promuove la riusabilità del codice: Con l'aiuto dei generici in Java, possiamo scrivere codice che funzionerà con diversi tipi di dati. Per esempio,

Diciamo che vogliamo ordinare gli elementi dell'array di vari tipi di dati come int, char, String ecc.

Fondamentalmente avremo bisogno di funzioni diverse per diversi tipi di dati.

Per semplicità utilizzeremo il Bubble sort.

Ma usando generici, possiamo ottenere la funzionalità di riusabilità del codice.

Giava




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) { //Dato che stiamo confrontando i tipi di dati non primitivi //dobbiamo usare la classe comparabile //la logica Bubble Sort for (int i = 0; i 1; i++) { for (int j = 0; j 1; j++) { if (a[j].compareTo(a[j + 1])> 0) { scambia(j, j + 1, a); } } } // Stampa gli elementi dopo l'ordinamento for (T i : a) { System.out.print(i + ', '); } System.out.println(); } public static void swap(int i, int j, T[] a) { T t = a[i]; a[i] = a[j]; a[j] = t; } }>

>

espressione regolare Java per
>

Produzione

Sorted Integer array : 6, 22, 41, 50, 58, 100, Sorted Character array : a, c, d, g, t, v, x, Sorted String array : Abhinay, Bharat, Chandu, Kalam, Rohit, Sam, Virat,>

Qui, abbiamo creato un metodo generico. Questo stesso metodo può essere utilizzato per eseguire operazioni su dati interi, dati stringa e così via.

5. Implementazione di algoritmi generici: Utilizzando i generici, possiamo implementare algoritmi che funzionano su diversi tipi di oggetti e, allo stesso tempo, sono anche indipendenti dai tipi.