Generika betyder parametriserade typer . Tanken är att tillåta typ (heltal, sträng, … etc. och användardefinierade typer) att vara en parameter för metoder, klasser och gränssnitt. Med Generics är det möjligt att skapa klasser som fungerar med olika datatyper. En entitet som klass, gränssnitt eller metod som fungerar på en parameteriserad typ är en generisk enhet.
Varför generika?
De Objekt är superklassen för alla andra klasser, och Objektreferens kan referera till vilket objekt som helst. Dessa funktioner saknar typsäkerhet. Generika lägger till den typen av säkerhetsfunktion. Vi kommer att diskutera den typen av säkerhetsfunktioner i senare exempel.
Generics i Java liknar mallar i C++. Till exempel, klasser som HashSet, ArrayList, HashMap, etc., använder generika mycket väl. Det finns några grundläggande skillnader mellan de två synsätten på generiska typer.
Typer av Java Generics
Generisk metod: Generisk Java-metod tar en parameter och returnerar något värde efter att ha utfört en uppgift. Det är precis som en normal funktion, men en generisk metod har typparametrar som citeras av faktisk typ. Detta gör att den generiska metoden kan användas på ett mer generellt sätt. Kompilatorn tar hand om den typ av säkerhet som gör det möjligt för programmerare att enkelt koda eftersom de inte behöver utföra långa, individuella typgjutningar.
Generiska klasser: En generisk klass implementeras precis som en icke-generisk klass. Den enda skillnaden är att den innehåller en typparametersektion. Det kan finnas mer än en typ av parameter, separerade med kommatecken. Klasserna, som accepterar en eller flera parametrar, kallas parametriserade klasser eller parameteriserade typer.
Generisk klass
Liksom C++ använder vi för att specificera parametertyper i generisk klassskapande. För att skapa objekt av en generisk klass använder vi följande syntax.
// To create an instance of generic class BaseType obj = new BaseType ()>
Notera: I parametertyp kan vi inte använda primitiver som 'int', 'char' eller '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());> > }> }> |
>
>Produktion
15 GeeksForGeeks>
Vi kan också skicka flera typparametrar i generiska klasser.
Java
uppdaterar 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();> > }> }> |
>
>Produktion
GfG 15>
Generiska funktioner:
Vi kan också skriva generiska funktioner som kan anropas med olika typer av argument baserat på vilken typ av argument som skickas till den generiska metoden. Kompilatorn hanterar varje metod.
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> );> > }> }> |
>
>Produktion
java.lang.Integer = 11 java.lang.String = GeeksForGeeks java.lang.Double = 1.0>
Generika fungerar endast med referenstyper:
När vi deklarerar en instans av en generisk typ måste typargumentet som skickas till parametern type vara en referenstyp. Vi kan inte använda primitiva datatyper som int , röding.
Test obj = new Test(20);>
Ovanstående rad resulterar i ett kompileringsfel som kan lösas med hjälp av typomslag för att kapsla in en primitiv typ.
objektklass i java
Men arrayer av primitiva typ kan skickas till parametern type eftersom arrayer är referenstyper.
ArrayList a = new ArrayList();>
Generiska typer skiljer sig beroende på deras typargument:
Tänk på följande Java-kod.
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> > }> }> |
>
>
Produktion:
error: incompatible types: Test cannot be converted to Test>
Även om iObj och sObj är av typen Test, är de referenser till olika typer eftersom deras typparametrar skiljer sig åt. Generika lägger till typsäkerhet genom detta och förhindrar fel.
Skriv parametrar i Java Generics
Typparametrarnas namnkonventioner är viktiga för att lära sig generika grundligt. De vanliga typparametrarna är följande:
är lika med metod java
- T – Typ
- E – Element
- K – Nyckel
- N – Antal
- V – Värde
Fördelar med generika:
Program som använder Generics har många fördelar jämfört med icke-generisk kod.
1. Kodåteranvändning: Vi kan skriva en metod/klass/gränssnitt en gång och använda den för vilken typ vi vill.
2. Typsäkerhet: Generika gör fel för att visas kompileringstid än vid körning (det är alltid bättre att känna till problem i din kod vid kompilering istället för att få din kod att misslyckas vid körning). Anta att du vill skapa en ArrayList som lagrar elevernas namn, och om programmeraren av misstag lägger till ett heltalsobjekt istället för en sträng, tillåter kompilatorn det. Men när vi hämtar dessa data från ArrayList, orsakar det problem under körning.
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> );> > }> }> |
>
>
Utgång:
Exception in thread 'main' java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at Test.main(Test.java:19)>
Hur löser generika detta problem?
När vi definierar ArrayList kan vi ange att den här listan endast kan ta strängobjekt.
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> );> > }> }> |
>
>
java delsträng
Produktion:
15: error: no suitable method found for add(int) al.add(10); ^>
3. Enskild typgjutning behövs inte: Om vi inte använder generika måste vi, i exemplet ovan, varje gång vi hämtar data från ArrayList, typcasta det. Typecasting vid varje hämtning är en stor huvudvärk. Om vi redan vet att vår lista bara innehåller strängdata behöver vi inte typcasta den varje gång.
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 främjar återanvändbarhet av kod: Med hjälp av generika i Java kan vi skriva kod som ska fungera med olika typer av data. Till exempel,
Låt oss säga att vi vill sortera arrayelementen för olika datatyper som int, char, String etc.
I grund och botten kommer vi att behöva olika funktioner för olika datatyper.
För enkelhetens skull kommer vi att använda Bubblesort.
Men genom att använda Generika, vi kan uppnå funktionen för återanvändning av kod.
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) { //När vi jämför de icke-primitiva datatyperna //måste vi använda Comparable class //Bubble Sort logic för (int i = 0; i 1; i++) { för (int j = 0; j 1; j++) { if (a[j].compareTo(a[j + 1])> 0) { swap(j, j + 1, a); } } } // Skriver ut elementen efter sorterade för (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; } }> |
>
tcp och ip-modell
>Produktion
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,>
Här har vi skapat en generisk metod. Samma metod kan användas för att utföra operationer på heltalsdata, strängdata och så vidare.
5. Implementera generiska algoritmer: Genom att använda generika kan vi implementera algoritmer som fungerar på olika typer av objekt, och samtidigt är de typsäkra också.