Vad är Generics i Java?

Generics i Java introducerades redan 2004 som en ny funktion i Java-programmeringsspråket och var en del av JDK 5-utgåvan. Det används mest tillsammans med Java-samlingsramen. Från idag är det en av de mest framstående och eftertraktade funktionerna i programmeringsspråket Java.

Generisk Java hittades av fyra individer, nämligen Gilad Bracha, Martin Odersky, David Stoutamire och Philip Wadler 1998. Det var en förlängning av Java-språket som stödde generiska typer. Det var tänkt att uppnå två huvudmål som är:

  1. Typ av säkerhet
  2. Kodåteranvändbarhet

Definition av generik i Java

Generics kan definieras som ett sätt att uppnå återanvändbarhet genom kod genom att definiera generiska klasser, gränssnitt, konstruktörer och metoder som kan användas med olika datatyper och också uppnå typsäkerhet genom att förklara datatypen som används i implementeringen i förväg, och därför eliminera chanserna för ett körtidfel.

Hur implementeras generika i Java?

Generik implementeras med vinkelfästena “”. Fästarna innehåller typparametern "T" i dem. Exempel, . Typparametern "T" är en platshållare som indikerar att en datatyp tilldelas den vid körning. Till exempel kommer en generisk klass att definieras som:

public class MyGenericClass (…)

Följande är parametrarna för standardtyp:

  • T: Typ
  • E: Element
  • N: Antal
  • K: Nyckel
  • V: värde

S, U, V och så vidare används för att definiera andra, tredje respektive fjärde parametrarna i fall multimarametern används.

Förstå generik i Java

Just nu undrar du vad som är typsäkerhet och hur fungerar det? Eller hur skiljer sig generiska klasser, gränssnitt, konstruktörer och metoder från våra vanliga klasser och metoder som gör dem återanvändbara? Låt oss ta reda på.

Java är ett statiskt typspråk kräver att du anger de "typen" som är datatypen för värdet som variabeln innehar innan du använder den.

Exempel: String myString =”eduCBA”;

Här är "String" datatypen, "myString" är den variabel som kommer att innehålla ett värde vars typ är String.

Om du försöker överföra ett booleskt värde istället för en sträng, till exempel:

String myBooleanStr = true;

Du får omedelbart ett kompileringstidsfel som anger "Typmatchning: kan inte konvertera från boolean till sträng".

Hur uppnår vi kodåteranvändbarhet med generik?

Låt oss nu definiera en vanlig metod:

public static void welcome(String name)(
System.out.println("welcome to " + name);
)

Denna metod kan endast åberopas genom att skicka en strängparameter. Till exempel:

welcome(“eduCBA”);

Dess produktion kommer att vara "välkommen till eduCBA".

Du kan dock inte åberopa den här metoden genom att kringgå andra datatyper som heltal eller booleska. Om du försöker göra det kommer du att uppmanas med ett kompileringstidsfel som anger "Metoden välkommen (String) i typen Runner är inte tillämplig för argumenten (boolean)". Det betyder att du inte kan skicka någon annan datatyp till en metod som bara accepterar en sträng som en parameter.

Detta innebär också att om du vill åberopa en liknande metod för en annan datatyp måste du skriva en ny metod som accepterar den önskade datatypen som en parameter. Denna funktion av omskrivningsmetoder med parametrar för olika datatyper kallas också metodöverbelastning. Den största nackdelen med detta är att det ökar storleken på din kod.

Men vi kan också använda Generics för att skriva om ovanstående metod och använda den för vilken datatyp vi behöver.

Definiera en generisk metod:

public static void welcome(T t)(
System.out.println("it is " + t);
)

Obs : Här är "t" ett objekt av typ T. T tilldelas den datatyp som används för att åberopa metoden.

Nu kan du återanvända den här metoden genom att anropa den för en sträng vid behov eller ett booleskt eller ett heltal eller någon annan datatyp.

welcome("educate");
Integer Myint = 1;
welcome(Myint)
welcome(true);

Ovanstående uttalanden ger nedanstående utgång:

Det är Educa
Det är 1
Det är sant

Därför, genom att använda generiska här kan vi återanvända vår metod för olika datatyper.

Hur uppnår vi typsäkerhet med generics?

En av de största skillnaderna mellan Arrays och Collection är att Arrays endast kan lagra homogena data, medan samlingar kan lagra heterogena data. Det vill säga samlingar kan lagra alla användardefinierade datatyper / objekt.

OBS: Samlingar kan bara innehålla objekt (användardefinierad datatyp) och inte en primitiv datatyp. För att arbeta med primitiva data använder typsamlingar wrapperklasser.

Låt oss nu överväga en ArrayList.

ArrayList myList = new ArrayList();

Låt oss lägga till data av typen String, heltal och dubbel till ArrayList-objektet.

myList.add("eduCBA");
myList.add(1);
myList.add(5.2);

När vi skriver ut ArrayList-objektet kan vi se att det har följande värden: (eduCBA, 1, 5.2).

Om du nu vill hämta dessa värden i variabler måste du skriva in dem.

String someStr = (String)myList.get(0);
Integer someInt = (Integer)myList.get(1);
Double someFlt = (Double)myList.get(2);

Om du inte skriver ut, kommer du att uppmanas med ett kompileringstidsfel som anger "Typmatchning: kan inte konvertera från objekt till sträng".

Från detta kan du dra slutsatsen att medan du hämtar objekten från din ArrayList måste du skriva in dem till deras respektive typer. Frågan som uppstår här är hur kommer du att veta vilken datatyp du vill skriva ut den till? I realtid kommer din ArrayList att innehålla tusentals poster och att skriva den till olika datatyper för varje enskilt objekt kommer inte att vara ett alternativ. Du kan sluta skriva den till fel datatyp. Vad händer då?

Den här gången får du inte ett kompileringstidsfel utan kastar ett körningsfel som anger "Undantag i tråd" main "java.lang.ClassCastException: java.lang.Integer kan inte kastas till java.lang.String på com.serviceClasess.Runner .main (Runner.java:43)”.

Eftersom vi inte kan garantera vilken typ av data som finns i en samling (i detta fall ArrayList), anses de inte vara säkra att använda med avseende på typ. Det är här generika spelar in för att ge typsäkerhet.

Använda ArrayList med Generics:

ArrayList myList = new ArrayList();

Lägg märke till att inuti vinkelfästena "", anges strängtyp vilket innebär att denna specifika implementering av ArrayList bara kan innehålla strängdata. Om du försöker lägga till någon annan datatyp till den kommer det helt enkelt att kasta kompileringstidsfel. Här har du gjort din ArrayList-typsäker genom att eliminera risken för att lägga till en annan datatyp annan än "String".

Nu när du har angett den datatyp som är tillåten att läggas till i din samling med hjälp av generik behöver du inte längre skriva in den när du hämtar dina data. Det är att du helt enkelt kan hämta dina data genom att skriva:

String someStr = myList.get(0);

Hur gör Generics i Java det så enkelt att arbeta?

Det hjälper till att göra dina samlingar typsäkra och ser till att din kod inte misslyckas vid en senare tidpunkt på grund av ett undantag för körning. Det sparar också kodaren från att behöva skriva alla objekt i samlingen för att göra kodutvecklingen snabbare och enklare. Genom att använda generiska klasser och metoder kan man också återanvända koden enligt den begärda datatypen under implementeringen.

Vad kan du göra mer med Generics i Java?

Hittills har vi sett hur vi kan uppnå typsäkerhet och kodåteranvändbarhet med generika. Låt oss nu titta på de andra funktioner som generika tillhandahåller. Dom är:

  1. Begränsade & flera avgränsade typer
  2. Skriv wildcards

Begränsad typ: Vid en begränsad typ är datatypen för en parameter begränsad till ett visst intervall. Detta uppnås med hjälp av nyckelordet "utökar".

Låt oss till exempel överväga en generisk klass med en begränsad typparameter som utökar Runnable-gränssnittet:

class myGenericClass()

Nu, medan du skapar sitt objekt i en annan klass:

myGenericClass myGen = new myGenericClass();

Ovanstående uttalande kommer att köras perfekt utan några fel. Det är i fallet med den avgränsade typen du kan passera samma klasstyp eller dess barnklasstyp. Du kan också binda parametertypen till ett gränssnitt och skicka implementeringarna när du åberopar den, som i vårt exempel ovan.

Vad händer om du försöker använda någon annan typ av parameter?

myGenericClass myGen = new myGenericClass();

I ovanstående fall får du ett kompileringstidsfel med angivelse av "Bound mismatch: Typen heltal är inte ett giltigt ersättare för typecast för typen myGenericClass".

Flera avgränsade typer: Vid flera avgränsade typer kan vi binda parametertypen till mer än en typ. Till exempel,

Class myGeneric()

I det här fallet kan du passera vilken typ som helst som utökar nummerklass och implementerar Runnable-gränssnitt. Men vid användning av flera avgränsade typer bör några saker noteras:

  1. Vi kan inte utöka mer än en klass åt gången.
  2. Vi kan utöka valfritt antal gränssnitt i taget att det inte finns någon gräns för gränssnitt.
  3. Klassnamnet bör alltid komma först följt av gränssnittsnamnet, om inte kommer det att leda till ett kompileringstidsfel.

Skriv wildcards: De representeras av “?” - frågetecken symbol. Den använder två huvudnyckelord:

sträcker sig (för att definiera övre gränsen) och super (för att definiera nedre gränser).

Till exempel,

ArrayList al

Detta ArrayList-objekt "al" kommer att innehålla alla data av typ T och alla dess underklasser.

ArrayList al

Detta ArrayList-objekt "al" kommer att innehålla alla data av typ T och alla dess superklass.

Fördelar med Generics i Java

1. Flexibilitet : Generics tillhandahåller vår kod flexibiliteten för att rymma olika datatyper med hjälp av generiska klasser och metoder.

2. Kodunderhåll och återanvändbarhet : På grund av generiska klasser och metoder behöver man inte skriva om koden, om kravet ändras i ett senare skede vilket gör koden lättare att underhålla och återanvända.

3. Typsäkerhet: Ger typsäkerhet till insamlingsramen genom att definiera den datatyp som samlingen kan innehålla i förväg och eliminera eventuella risker för fel vid körning på grund av ClassCastException.

4. Eliminera behovet av att typecast: Eftersom de datatyper som innehas av samlingarna redan är bestämda behöver man inte skriva det vid tidpunkten för hämtning. Detta minskar kodens längd och minskar också en kodares ansträngning.

Generik i Java-färdigheter

För att arbeta med Generics bör du vara väl förtrogen med grunderna i Java. Du bör förstå hur typkontroll och typgjutning fungerar. Grundlig kunskap om andra begrepp som överbelastning av metoder, förhållandet mellan föräldrar och barnklasser, gränssnitt och deras implementeringar är nödvändiga. Att förstå skillnaden mellan primitiva datatyper (systemdefinierad datatyp) och objekt (användardefinierad datatyp) är avgörande när det gäller att arbeta med insamlingsramen.

Varför ska vi använda Generics i Java?

Att använda generika gör vår kod mer underhållbar eftersom det minskar behovet av att skriva om datatypspecifik kod varje gång det krävs förändringar. Genom att använda generisk avgränsad typ kan du begränsa datatypen och samtidigt ge din kod flexibilitet genom att definiera dess intervall. Det är mindre troligt att din kod misslyckas vid en senare tidpunkt, eftersom den ger typsäkerhet vilket gör din kod mindre felaktig.

Räckvidd för generik i Java

Generics omfattning är begränsad till att sammanställa tid. Det betyder att generikekoncept endast är tillämpligt vid sammanställningstid men inte vid körtid. Till exempel,

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

Här är alla ovanstående fyra uttalanden en och samma. De tillåter att alla typer av data läggs till i listobjektet.

Slutsats

Generics gör kodningen enkel för en kodare. Det minskar chansen att möta ClassCastException vid körning genom att tillhandahålla stark typkontroll. Eliminerar helt behovet av typgjutning vilket innebär att mindre kod behöver skrivas. Det ger oss möjligheten att utveckla generiska algoritmer som är oberoende av datatypen de arbetar med.

Rekommenderade artiklar

Detta har varit en guide till Vad är Generics i Java ?. Här diskuterade vi färdigheter, omfattning, arbete, förståelse och fördelar med generik i Java. Du kan också gå igenom våra andra föreslagna artiklar för att lära dig mer -

  1. Vad är Common Gateway Interface
  2. Hur man installerar Java 8
  3. vad är soapUI
  4. Vad är JavaScript?
  5. Java Booleans

Kategori: