Hvad er Generics i Java?

Generics i Java blev introduceret i 2004 som en ny funktion i Java-programmeringssprog og var en del af JDK 5-udgivelsen. Det bruges mest sammen med Java-samlingens rammer. I dag er det et af de mest fremtrædende og efterspurgte træk ved Java-programmeringssprog.

Generisk Java blev fundet af fire personer, nemlig Gilad Bracha, Martin Odersky, David Stoutamire og Philip Wadler i 1998. Det var en udvidelse af Java-sproget, der understøttede generiske typer. Det var beregnet til at nå to hovedmål, som er:

  1. Type sikkerhed
  2. Genanvendelse af kode

Definition af generika i Java

Generics kan defineres som en måde at opnå kodegenanvendelighed ved at definere generiske klasser, grænseflader, konstruktører og metoder, der kan bruges med forskellige datatyper og også opnå typesikkerhed ved at erklære datatypen, der bruges i implementeringen på forhånd, og derfor eliminere chancerne for en run-time-fejl.

Hvordan implementeres generika i Java?

Generiske enheder implementeres ved hjælp af vinkelbeslag “”. Konsolerne indeholder typeparameteren “T” i dem. Eksempel. Typeparameteren "T" er en pladsholder, der indikerer, at en datatype vil blive tildelt den på kørselstidspunktet. For eksempel defineres en generisk klasse som:

public class MyGenericClass (…)

Følgende er standardtypeparametrene:

  • T: Type
  • E: Element
  • N: Antal
  • K: nøgle
  • V: Værdi

S, U, V osv. Bruges til at definere henholdsvis anden, tredje og fjerde parametre i tilfælde af, at der anvendes multiparameter.

Forstå generik i Java

På nuværende tidspunkt kan du undre dig over, hvad der er typesikkerhed, og hvordan fungerer det? Eller hvordan er generiske klasser, grænseflader, konstruktører og metoder forskellig fra vores almindelige klasser og metoder, der gør dem genanvendelige? Lad os finde ud af det.

Java, der er et statisk typisk sprog, kræver, at du erklærer “typen”, der er datatypen for den værdi, som variablen opbevarer, før den bruges.

Eksempel: String myString =”eduCBA”;

Her er "streng" datatypen, "myString" er den variabel, der vil indeholde en værdi, hvis type er streng.

Hvis du forsøger at videregive en boolsk værdi i stedet for en streng, for eksempel:

String myBooleanStr = true;

Du får straks en kompileringstid-fejl med angivelse af "Type mismatch: kan ikke konvertere fra boolsk til streng".

Hvordan opnår vi genanvendelse af koden med Generics?

Lad os nu definere en almindelig metode:

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

Denne metode kan kun påberåbes ved at videregive en strengparameter. For eksempel:

welcome(“eduCBA”);

Dets output vil være "velkommen til eduCBA".

Du kan dog ikke påberope denne metode ved at omgå nogen andre datatyper, såsom heltal eller boolsk. Hvis du prøver at gøre det, bliver du bedt om en fejl i kompileringstid, der angiver "Metodens velkomst (streng) i typen Runner er ikke relevant for argumenterne (boolsk)". Betydning at du ikke kan videregive nogen anden datatype til en metode, der kun accepterer en streng som en parameter.

Dette betyder også, at hvis du ønsker at påkalde en lignende metode for en anden datatype, bliver du nødt til at skrive en ny metode, der accepterer den krævede datatype som en parameter. Denne funktion ved omskrivning af metoder med parametre af forskellige datatyper er også kendt som metodeoverbelastning. Den største ulempe ved dette er, at det øger størrelsen på din kode.

Vi kan imidlertid også bruge Generics til at omskrive ovennævnte metode og bruge den til enhver datatype, vi har brug for.

Definition af en generisk metode:

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

Bemærk : Her er "t" et objekt af type T. T tildeles den datatype, der bruges til at påkalde metoden.

Nu kan du genbruge denne metode ved at påkalde den til en streng når det er nødvendigt eller en boolsk eller et heltal eller en hvilken som helst anden datatype.

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

Ovenstående udsagn giver følgende output:

Det er Educa
Det er 1
Det er sandt

Derfor ved at bruge generiske her er vi i stand til at genbruge vores metode til forskellige datatyper.

Hvordan opnår vi typesikkerhed ved hjælp af Generics?

En af de største forskelle mellem Arrays og Collection er, at Arrays kun kan gemme homogene data, mens samlinger kan gemme heterogene data. Det vil sige, at samlinger kan gemme enhver brugerdefineret datatype / objekter.

BEMÆRK: Samlinger kan kun indeholde objekter (brugerdefineret datatype) og ikke en primitiv datatype. For at arbejde med primitive data bruger typesamlinger indpakningsklasser.

Lad os nu overveje en ArrayList.

ArrayList myList = new ArrayList();

Lad os tilføje data af typen streng, heltal og dobbelt til ArrayList-objektet.

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

Ved udskrivning af ArrayList-objektet kan vi se, at det indeholder følgende værdier: (eduCBA, 1, 5.2).

Hvis du nu ønsker at hente disse værdier i variabler, skal du typecastecast dem.

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

I tilfælde af at du ikke typecast, bliver du bedt om en fejl i kompileringstid, der angiver "Type mismatch: can not convert from Object to String".

Fra dette kan du konkludere, at mens du henter objekterne fra din ArrayList, skal du indtaste dem til deres respektive typer. Spørgsmålet, der opstår her, er, hvordan vil du vide, hvilken datatype du skal typecast det til? I realtid vil din ArrayList indeholde tusinder af poster og typecasting den til forskellige datatyper for hvert individuelt objekt vil ikke være en mulighed. Du kan muligvis ende med at skrive den til den forkerte datatype. Hvad sker der så?

Denne gang får du ikke en compile time-fejl, men kaster en runtime-fejl med angivelse af "Undtagelse i tråd" main "java.lang.ClassCastException: java.lang.Integer kan ikke sendes til java.lang.String på com.serviceClasess.Runner .main (Runner.java:43)”.

Da vi ikke kan garantere den type data, der findes i en samling (i dette tilfælde ArrayList), betragtes de som ikke sikre at bruge med hensyn til type. Det er her generika kommer i spil for at give typesikkerhed.

Brug af ArrayList med Generics:

ArrayList myList = new ArrayList();

Bemærk, at inden for vinkelbeslag “” er strengtype specificeret, hvilket betyder, at denne specifikke implementering af ArrayList kun kan indeholde data om strengetype. Hvis du prøver at tilføje nogen anden datatype til det, kaster det simpelthen compile time error. Her har du gjort din ArrayList-type sikker ved at fjerne sin chance for at tilføje en anden datatype bortset fra “String”.

Nu, hvor du har angivet den datatype, der er tilladt at føjes til din samling ved hjælp af generiske, behøver du ikke længere at indtaste den, mens du henter dine data. Det er, at du blot kan hente dine data ved at skrive:

String someStr = myList.get(0);

Hvordan gør Generics i Java det så nemt at arbejde?

Det hjælper med at gøre dine samlinger typesikre og sikre dig at din kode ikke svigter på et senere tidspunkt på grund af en undtagelse af kørselstid. Det sparer også koderen fra at skulle typecaste hvert objekt i samlingen, hvilket gør kodeudviklingen hurtigere og lettere. Ved at anvende generiske klasser og metoder kan man også genbruge koden som pr. Den krævede datatype under implementeringen.

Hvad kan du ellers gøre med Generics i Java?

Indtil videre har vi set, hvordan vi kan opnå typesikkerhed og genanvendelse af koder med generika. Lad os nu se på de andre funktioner generika leverer. De er:

  1. Afgrænsede & flere afgrænsede typer
  2. Skriv wildcards

Afgrænset type: I tilfælde af en afgrænset type er datatypen for en parameter afgrænset til et bestemt område. Dette opnås ved hjælp af nøgleordet "udvider".

Lad os f.eks. Overveje en generisk klasse med en parameter med begrænset type, der udvider Runnable interface:

class myGenericClass()

Nu, mens du opretter sit objekt i en anden klasse:

myGenericClass myGen = new myGenericClass();

Ovenstående udsagn udføres perfekt uden fejl. Det er tilfældet med den afgrænsede type, du kan videregive den samme klassetype eller dens underklassetype. Du kan også binde parametertypen til en grænseflade og videregive dens implementeringer, når du påberåber den, som i tilfældet med vores eksempel ovenfor.

Hvad sker der, hvis du prøver at bruge nogen anden type parameter?

myGenericClass myGen = new myGenericClass();

I ovenstående tilfælde får du en kompileringstid-fejl med angivelse af "Bound mismatch: Type Integer er ikke en gyldig erstatning for typecastet af typen myGenericClass".

Flere afgrænsede typer: I tilfælde af flere afgrænsede typer kan vi binde parameterdatatypen til mere end en type. For eksempel,

Class myGeneric()

I dette tilfælde kan du videregive enhver type, der udvider nummerklassen og implementerer Runnable interface. Ved brug af flere afgrænsede typer skal der dog bemærkes få ting:

  1. Vi kan ikke udvide mere end en klasse ad gangen.
  2. Vi kan udvide ethvert antal grænseflader ad gangen, at der ikke er nogen grænse for grænseflader.
  3. Klassens navn skal altid komme først efterfulgt af interfacenavnet, hvis ikke, vil det resultere i en kompileringstid-fejl.

Type wildcards: De er repræsenteret med “?” - spørgsmålstegn symbol. Det gør brug af to hovednøgleord:

strækker sig (for at definere øvre grænse) og super (for at definere nedre grænser).

For eksempel,

ArrayList al

Dette ArrayList-objekt “al” vil indeholde alle data af type T og alle dets underklasser.

ArrayList al

Dette ArrayList-objekt “al” vil indeholde alle data af type T og alle dets superklasser.

Fordele ved Generics i Java

1. Fleksibilitet : Generics giver vores kode fleksibiliteten til at rumme forskellige datatyper ved hjælp af generiske klasser og metoder.

2. Vedligeholdelse og genanvendelse af kode: På grund af generiske klasser og metoder behøver man ikke at omskrive koden, i tilfælde af ændringer i krav på et senere tidspunkt, hvilket gør koden lettere at vedligeholde og genbruge.

3. Typesikkerhed: Giver typesikkerhed til indsamlingsrammen ved at definere den datatype, som samlingen kan indeholde på forhånd, og eliminere eventuelle chancer for fejl på kørsel på grund af ClassCastException.

4. Fjernelse af behovet for typecast: Da de datatyper, der er i samlingerne, allerede er bestemt, behøver man ikke at typecast det på hentningstidspunktet. Dette reducerer kodens længde og reducerer også en koders indsats.

Generik i Java-færdigheder

For at arbejde med Generics skal du være velkyndig med det grundlæggende i Java. Du skal forstå, hvordan typekontrol og type casting fungerer. Grundig viden om andre koncepter, såsom overbelastning af metoden, forholdet mellem forældre og børn klasser, grænseflader og deres implementeringer er nødvendige. Også forståelse af forskellen mellem primitive datatyper (systemdefineret datatype) og objekter (brugerdefineret datatype) er afgørende, når det gælder arbejde med indsamlingsrammen.

Hvorfor skal vi bruge Generics i Java?

Brug af generiske enheder gør vores kode mere vedligeholdelig, da det reducerer behovet for at omskrive datatypespecifik kode hver gang der sker ændringer i kravet. Ved at bruge generisk afgrænset type kan du begrænse datatypen og samtidig give din kode fleksibilitet ved at definere dens rækkevidde. Det er mindre sandsynligt, at din kode mislykkes på et senere tidspunkt, da den giver typesikkerhed, hvilket gør din kode mindre udsat for fejl.

Omfang til generik i Java

Generiske omfang er begrænset til kompileringstid. Det betyder, at generisk koncept kun kan anvendes på kompileringstidspunktet, men ikke på kørselstidspunktet. For eksempel,

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

Her er alle ovenstående fire udsagn en og samme. De tillader tilføjelse af enhver type data til listeobjektet.

Konklusion

Generics gør kodning let for en koder. Det mindsker chancerne for at møde ClassCastException ved kørsel ved at tilvejebringe stærk typekontrol. Eliminerer behovet for type-casting fuldstændigt, hvilket betyder, at mindre kode skal skrives. Det giver os muligheden for at udvikle generiske algoritmer, der er uafhængige af den datatype, de arbejder med.

Anbefalede artikler

Dette har været en guide til Hvad er Generics i Java ?. Her diskuterede vi Færdigheder, Omfang, arbejde, forståelse og fordel ved Generics i Java. Du kan også gennemgå vores andre foreslåede artikler for at lære mere -

  1. Hvad er fælles gateway-grænseflade
  2. Sådan installeres Java 8
  3. hvad er soapUI
  4. Hvad er JavaScript?
  5. Java Booleans

Kategori: