logo

Generika v Javě

Generika prostředek parametrizované typy . Cílem je umožnit, aby typ (Integer, String, … atd. a uživatelem definované typy) byl parametrem metod, tříd a rozhraní. Pomocí Generics je možné vytvářet třídy, které pracují s různými datovými typy. Entita, jako je třída, rozhraní nebo metoda, která funguje na parametrizovaném typu, je generická entita.

Proč Generika?

The Objekt je nadtřídou všech ostatních tříd a odkaz na objekt může odkazovat na jakýkoli objekt. Tyto vlastnosti postrádají typovou bezpečnost. Generika přidávají tento typ bezpečnostní funkce. Tento typ bezpečnostní funkce probereme v dalších příkladech.



Generika v Javě jsou podobná šablonám v C++. Například třídy jako HashSet, ArrayList, HashMap atd. velmi dobře používají generika. Mezi těmito dvěma přístupy ke generickým typům jsou některé zásadní rozdíly.

Typy Java Generics

Obecná metoda: Obecná metoda Java vezme parametr a po provedení úlohy vrátí nějakou hodnotu. Je to přesně jako normální funkce, ale generická metoda má parametry typu, které jsou citovány podle skutečného typu. To umožňuje použít obecnou metodu obecnějším způsobem. Překladač se stará o typ bezpečnosti, který umožňuje programátorům snadno kódovat, protože nemusí provádět dlouhé odlitky jednotlivých typů.

Obecné třídy: Obecná třída je implementována přesně jako negenerická třída. Jediný rozdíl je v tom, že obsahuje sekci parametru typu. Parametrů může být více než jeden, oddělených čárkou. Třídy, které přijímají jeden nebo více parametrů, jsou známé jako parametrizované třídy nebo parametrizované typy.



Obecná třída

Stejně jako C++ používáme k určení typů parametrů při vytváření obecných tříd. K vytvoření objektů generické třídy používáme následující syntaxi.

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

Poznámka: V typu Parametr nemůžeme používat primitiva jako „int“, „char“ nebo „double“.

Jáva






// 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ýstup

15 GeeksForGeeks>

V obecných třídách můžeme také předat více parametrů Type.

Jáva

vrací pole 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();> >}> }>

>

>

Výstup

GfG 15>

Obecné funkce:

Můžeme také psát generické funkce, které lze volat s různými typy argumentů na základě typu argumentů předávaných generické metodě. Kompilátor zpracovává každou metodu.

Jáva




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

>

>

java matematika
Výstup

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

Generika fungují pouze s referenčními typy:

Když deklarujeme instanci obecného typu, argument type předaný parametru type musí být referenční typ. Nemůžeme používat primitivní datové typy jako např int , char.

Test obj = new Test(20);>

Výše uvedený řádek vede k chybě při kompilaci, kterou lze vyřešit pomocí obálky typu k zapouzdření primitivního typu.

Ale pole primitivního typu lze předat parametru type, protože pole jsou referenční typy.

ArrayList a = new ArrayList();>

Obecné typy se liší v závislosti na jejich typových argumentech:

Zvažte následující kód Java.

Jáva




// 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ýstup:

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

Přestože iObj a sObj jsou typu Test, jedná se o odkazy na různé typy, protože jejich parametry typu se liší. Generika tím zvyšují bezpečnost typu a zabraňují chybám.

Zadejte parametry v Java Generics

Konvence pojmenovávání parametrů typů jsou důležité pro důkladné naučení se generikám. Běžné parametry typu jsou následující:

regresní výraz v Javě
  • T – typ
  • E – prvek
  • K – klíč
  • N – Číslo
  • V – Hodnota

Výhody generik:

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

1. Opětovné použití kódu: Metodu/třídu/rozhraní můžeme napsat jednou a použít ji pro jakýkoli typ, který chceme.

2. Typ zabezpečení: Generika způsobují chyby, aby se objevily v době kompilace než v době běhu (Vždy je lepší znát problémy v kódu v době kompilace, než aby váš kód selhal za běhu). Předpokládejme, že chcete vytvořit ArrayList, který ukládá jména studentů, a pokud programátor omylem přidá místo řetězce celočíselný objekt, kompilátor to umožní. Když však tato data načteme z ArrayList, způsobí to problémy za běhu.

Jáva




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

>

>

Výstup :

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

Jak generika řeší tento problém?

Při definování ArrayList můžeme určit, že tento seznam může obsahovat pouze objekty typu String.

Jáva




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

>

java int v řetězci
>

Výstup:

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

3. Odlévání jednotlivých typů není potřeba: Pokud nepoužijeme generika, pak ve výše uvedeném příkladu pokaždé, když načítáme data z ArrayList, musíme je přetypovat. Přetypování při každé vyhledávací operaci je velká bolest hlavy. Pokud již víme, že náš seznam obsahuje pouze data řetězce, nemusíme je pokaždé přetypovat.

Jáva




// 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 znovupoužitelnost kódu: S pomocí generik v Javě můžeme napsat kód, který bude pracovat s různými typy dat. Například,

Řekněme, že chceme třídit prvky pole různých datových typů, jako je int, char, String atd.

V zásadě budeme potřebovat různé funkce pro různé typy dat.

Pro jednoduchost budeme používat Bubble sort.

Ale používáním generika, můžeme dosáhnout funkce znovupoužitelnosti kódu.

Jáva




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) { //Protože porovnáváme neprimitivní datové typy //musíme použít Comparable class //Bubble Sort logiku pro (int i = 0; i 1; i++) { pro (int j = 0 j 1; } } } // Tisk prvků po třídění pro (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; } }>

>

C#
>

Výstup

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

Zde jsme vytvořili generickou metodu. Stejnou metodu lze použít k provádění operací s celočíselnými daty, řetězcovými daty a tak dále.

5. Implementace obecných algoritmů: Pomocí generik můžeme implementovat algoritmy, které fungují na různých typech objektů a zároveň jsou typově bezpečné.