logo

Generiká v Jave

Generiká znamená parametrizované typy . Myšlienkou je umožniť, aby typ (Integer, String, ... atď. a užívateľsky definované typy) bol parametrom metód, tried a rozhraní. Pomocou Generics je možné vytvárať triedy, ktoré pracujú s rôznymi typmi údajov. Entita, ako je trieda, rozhranie alebo metóda, ktorá funguje na parametrizovanom type, je generická entita.

Prečo generiká?

The Objekt je nadtrieda všetkých ostatných tried a odkaz na objekt môže odkazovať na akýkoľvek objekt. Týmto vlastnostiam chýba typová bezpečnosť. Generiká pridávajú tento typ bezpečnostného prvku. O tomto type bezpečnostnej funkcie budeme diskutovať v neskorších príkladoch.



Generiká v Jave sú podobné šablónam v C++. Napríklad triedy ako HashSet, ArrayList, HashMap atď. veľmi dobre využívajú generiká. Medzi týmito dvoma prístupmi ku generickým typom sú niektoré zásadné rozdiely.

Typy Java Generics

Všeobecná metóda: Generic Java metóda berie parameter a vracia nejakú hodnotu po vykonaní úlohy. Je to presne ako normálna funkcia, avšak generická metóda má parametre typu, ktoré sú citované podľa skutočného typu. To umožňuje, aby sa generická metóda používala všeobecnejšie. Kompilátor sa stará o typ bezpečnosti, ktorý umožňuje programátorom ľahko kódovať, pretože nemusia vykonávať dlhé, individuálne typové odliatky.

Všeobecné triedy: Generická trieda je implementovaná presne ako negenerická trieda. Jediný rozdiel je v tom, že obsahuje sekciu parametrov typu. Môže existovať viacero typov parametrov oddelených čiarkou. Triedy, ktoré akceptujú jeden alebo viac parametrov, sú známe ako parametrizované triedy alebo parametrizované typy.



Generická trieda

Podobne ako C++ používame na špecifikovanie typov parametrov pri vytváraní generických tried. Na vytvorenie objektov generickej triedy používame nasledujúcu syntax.

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

Poznámka: V type Parameter nemôžeme použiť primitívy ako „int“, „char“ alebo „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());> >}> }>

>

>

Výkon

15 GeeksForGeeks>

Vo všeobecných triedach môžeme tiež odovzdať viacero parametrov typu.

Java

anakonda vs pytónový had




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

>

>

Výkon

GfG 15>

Všeobecné funkcie:

Môžeme tiež napísať generické funkcie, ktoré možno volať s rôznymi typmi argumentov na základe typu argumentov odovzdaných generickej metóde. Kompilátor spracováva každú metódu.

Java




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

>

linux premenovať adresár

>

Výkon

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

Generiká fungujú len s referenčnými typmi:

Keď deklarujeme inštanciu všeobecného typu, argument typu odovzdaný parametru typu musí byť typ odkazu. Nemôžeme použiť primitívne dátové typy ako napr int , char.

Test obj = new Test(20);>

Vyššie uvedený riadok vedie k chybe v čase kompilácie, ktorú možno vyriešiť pomocou obalov typu na zapuzdrenie primitívneho typu.

Ale polia primitívnych typov môžu byť odovzdané parametru typu, pretože polia sú referenčné typy.

ArrayList a = new ArrayList();>

Všeobecné typy sa líšia v závislosti od ich typových argumentov:

Zvážte nasledujúci kód 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> >}> }>

>

>

Výkon:

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

Aj keď iObj a sObj sú typu Test, sú to odkazy na rôzne typy, pretože ich parametre typu sa líšia. Generiká týmto pridávajú bezpečnosť typu a zabraňujú chybám.

Typ parametrov v Java Generics

Konvencie pomenovania parametrov typu sú dôležité na dôkladné naučenie sa generík. Bežné parametre typu sú nasledovné:

výlet ale
  • T – typ
  • E – prvok
  • K – kľúč
  • N – Číslo
  • V – Hodnota

Výhody generík:

Programy, ktoré používajú Generics, majú mnoho výhod oproti negenerickému kódu.

1. Opätovné použitie kódu: Metódu/triedu/rozhranie môžeme napísať raz a použiť ju pre akýkoľvek typ, ktorý chceme.

2. Bezpečnosť typu: Generiká spôsobujú chyby, aby sa zobrazili v čase kompilácie ako v čase spustenia (vždy je lepšie poznať problémy vo vašom kóde v čase kompilácie, než aby váš kód zlyhal v čase spustenia). Predpokladajme, že chcete vytvoriť ArrayList, ktorý ukladá mená študentov, a ak omylom programátor pridá celočíselný objekt namiesto reťazca, kompilátor to umožní. Keď však získame tieto údaje z ArrayList, spôsobí to problémy za behu.

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

java nahradiť všetok reťazec

>

>

Výkon :

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

Ako generiká riešia tento problém?

Pri definovaní ArrayList môžeme určiť, že tento zoznam môže obsahovať iba objekty typu 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>);> >}> }>

>

>

Výkon:

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

3. Odlievanie jednotlivých typov nie je potrebné: Ak nepoužijeme generiká, potom vo vyššie uvedenom príklade vždy, keď získavame údaje z ArrayList, musíme ich pretypovať. Pretypovanie pri každej vyhľadávacej operácii je veľká bolesť hlavy. Ak už vieme, že náš zoznam obsahuje iba reťazcové údaje, nemusíme ich zakaždým pretypovať.

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. Generics podporuje opätovné použitie kódu: Pomocou generík v Jave môžeme napísať kód, ktorý bude pracovať s rôznymi typmi údajov. Napríklad,

Povedzme, že chceme triediť prvky poľa rôznych typov údajov, ako sú int, char, String atď.

V zásade budeme potrebovať rôzne funkcie pre rôzne typy údajov.

Pre jednoduchosť budeme používať Bubble sort.

Ale používaním generiká, môžeme dosiahnuť funkciu opätovnej použiteľnosti kódu.

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) { //Pri porovnávaní neprimitívnych dátových typov //musíme použiť Comparable class //Bubble Sort logiku for (int i = 0; i 1; i++) { for (int j = 0 j 1; } } } // Tlač prvkov po triedení pre (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; } }>

>

vba
>

Výkon

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,>

Tu sme vytvorili generickú metódu. Rovnakú metódu možno použiť na vykonávanie operácií s celočíselnými údajmi, reťazcovými údajmi atď.

5. Implementácia generických algoritmov: Použitím generík môžeme implementovať algoritmy, ktoré fungujú na rôznych typoch objektov a zároveň sú typovo bezpečné.