Hva er Generics i Java?

Generics i Java ble introdusert i 2004 som en ny funksjon i Java-programmeringsspråket og var en del av JDK 5-utgivelsen. Det er mest brukt sammen med Java-samlingsrammen. Per i dag er det en av de mest fremtredende og etterspurte funksjonene i programmeringsspråket Java.

Generisk Java ble funnet av fire individer, nemlig Gilad Bracha, Martin Odersky, David Stoutamire og Philip Wadler i 1998. Det var en forlengelse av Java-språket som støttet generiske typer. Det var ment å oppnå to hovedmål som er:

  1. Type sikkerhet
  2. Gjenbruk av kode

Definisjon av generikk i Java

Generics kan defineres som en måte å oppnå gjenbruk av kode ved å definere generiske klasser, grensesnitt, konstruktører og metoder som kan brukes med forskjellige datatyper og også oppnå typesikkerhet ved å erklære datatypen som blir brukt i implementeringen på forhånd, og derfor eliminere sjansene for en kjøretidsfeil.

Hvordan blir generikk implementert i Java?

Generiske modeller implementeres ved bruk av kantete parenteser “”. Beslagene inneholder typeparameteren “T” i dem. Eksempel, . Typeparameteren “T” er en plassholder som indikerer at en datatype vil bli tilordnet den ved kjøretid. For eksempel vil en generisk klasse bli definert som:

public class MyGenericClass (…)

Følgende er standardtypeparametere:

  • T: Type
  • E: Element
  • N: Antall
  • K: Nøkkel
  • V: Verdi

S, U, V og så videre brukes til å definere henholdsvis andre, tredje og fjerde parameter i tilfelle multiparameter blir brukt.

Forstå generikk i Java

Nå lurer du kanskje på hva som er typesikkerhet, og hvordan fungerer det? Eller hvordan er generiske klasser, grensesnitt, konstruktører og metoder forskjellige fra våre vanlige klasser og metoder som gjør dem gjenbrukbare? La oss finne det ut.

Java som et statisk typisk språk krever at du erklærer "typen" som er datatypen til verdien som blir holdt av variabelen før du bruker den.

Eksempel: String myString =”eduCBA”;

Her er "String" datatypen, "myString" er variabelen som vil inneholde en verdi hvis type er String.

Hvis du prøver å gi en boolsk verdi i stedet for en streng, for eksempel:

String myBooleanStr = true;

Du vil øyeblikkelig få en kompilertidsfeil som sier "Type mismatch: can not convert from boolean to String".

Hvordan oppnår vi gjenbruk av kode med generikk?

La oss nå definere en vanlig metode:

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

Denne metoden kan bare påberopes ved å sende en strengparameter. For eksempel:

welcome(“eduCBA”);

Produksjonen vil være "velkommen til eduCBA".

Du kan imidlertid ikke påberope deg denne metoden ved å omgå andre datatyper som heltall eller boolsk. Hvis du prøver å gjøre det, vil du bli bedt om en feil i kompileringstid som sier "Metoden velkommen (streng) i typen Runner er ikke relevant for argumentene (boolean)." Dette betyr at du ikke kan overføre noen annen datatype til en metode som bare godtar en streng som en parameter.

Dette betyr også at hvis du ønsker å påkalle en lignende metode for en annen datatype, må du skrive en ny metode som godtar den nødvendige datatypen som en parameter. Denne funksjonen ved å skrive om metoder med parametere av forskjellige datatyper er også kjent som metodebelastning. Den største ulempen med dette er at den øker størrelsen på koden din.

Imidlertid kan vi også bruke Generics til å skrive den ovennevnte metoden og bruke den til alle datatyper vi trenger.

Definere en generisk metode:

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

Merk : Her er "t" et objekt av type T. T vil bli tildelt datatypen som brukes til å påkalle metoden.

Nå kan du bruke denne metoden ved å påkalle den for en streng når det er nødvendig, eller en boolsk eller et helt tall eller en hvilken som helst annen datatype.

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

Ovennevnte utsagn vil gi følgende utdata:

Det er Educa
Det er 1
Det er sant

Derfor kan vi bruke generiske metoder her til å bruke metoden vår for forskjellige datatyper.

Hvordan oppnår vi typesikkerhet ved å bruke generikk?

En av de største forskjellene mellom Arrays og Collection er at Arrays kun kan lagre homogene data, mens samlinger kan lagre heterogene data. Det vil si at samlinger kan lagre hvilken som helst brukerdefinert datatype / objekter.

MERKNAD: Samlinger kan bare inneholde objekter (brukerdefinert datatype) og ikke en primitiv datatype. For å jobbe med primitive data, bruker typesamlinger innpakningsklasser.

La oss nå vurdere en ArrayList.

ArrayList myList = new ArrayList();

La oss legge til data av typen Streng, heltall og dobbelt til ArrayList-objektet.

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

Når vi skriver ut ArrayList-objektet, kan vi se at det inneholder følgende verdier: (eduCBA, 1, 5.2).

Hvis du ønsker å hente disse verdiene inn i variabler, må du typecastecast dem.

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

I tilfelle du ikke skriver, vil du bli bedt om en feil med kompileringstid som sier "Type mismatch: can not convert from Object to String".

Fra dette kan du konkludere med at mens du henter gjenstandene fra ArrayList, må du skrive dem til hver sin type. Spørsmålet som melder seg her er hvordan vil du vite hvilken datatype du vil typecast den til? I sanntid vil ArrayList inneholde tusenvis av poster og å skrive den til forskjellige datatyper for hvert enkelt objekt vil ikke være et alternativ. Du kan ende opp med å skrive den til feil datatype. Hva skjer da?

Denne gangen vil du ikke få en kompilertidsfeil, men vil kaste en kjøretidsfeil som sier “Unntak i tråd“ hoved ”java.lang.ClassCastException: java.lang.Integer kan ikke sendes til java.lang.String på com.serviceClasess.Runner .main (Runner.java:43)”.

Siden vi ikke kan garantere hvilken type data som er til stede i en samling (i dette tilfellet ArrayList), anses de som ikke trygge å bruke med hensyn til type. Det er her generika spiller inn for å gi trygghet.

Bruke ArrayList med Generics:

ArrayList myList = new ArrayList();

Legg merke til at inne i vinkel parenteser “”, er strengtype spesifisert som betyr at denne spesielle implementeringen av ArrayList bare kan inneholde data om strengtype. Hvis du prøver å legge til noen annen datatype til det, vil det ganske enkelt kaste kompileringstidsfeil. Her har du gjort ArrayList-typen trygg ved å eliminere sjansen for å legge til en annen datatype annet enn “String”.

Nå som du har spesifisert datatypen som er tillatt å bli lagt til i samlingen din ved hjelp av generiske data, trenger du ikke lenger skrive inn den mens du henter dataene dine. Det er at du bare kan hente dataene dine ved å skrive:

String someStr = myList.get(0);

Hvordan gjør Generics i Java det enkelt å jobbe?

Det hjelper med å gjøre samlingene dine trygge og dermed sørge for at koden ikke svikter på et senere tidspunkt på grunn av et unntak av kjøretid. Det sparer også koderen fra å måtte typecaste hvert objekt i samlingen, noe som gjør kodeutviklingen raskere og enklere. Ved å benytte generiske klasser og metoder kan man også gjenbruke koden som per de nødvendige datatypene under implementering.

Hva annet kan du gjøre med Generics i Java?

Så langt har vi sett hvordan vi kan oppnå typesikkerhet og gjenbruk av kode med generiske midler. La oss nå se på de andre funksjonene generika gir. De er:

  1. Begrensede og flere avgrensede typer
  2. Skriv inn jokertegn

Begrenset type: I tilfelle av en avgrenset type er datatypen til en parameter avgrenset til et bestemt område. Dette oppnås ved hjelp av søkeordet "utvider".

La oss for eksempel vurdere en generisk klasse med en begrenset type parameter som utvider Runnable-grensesnitt:

class myGenericClass()

Nå, mens du lager objektet i en annen klasse:

myGenericClass myGen = new myGenericClass();

Ovennevnte uttalelse vil utføres perfekt uten feil. Det er i tilfelle av den avgrensede typen du kan passere den samme klassetypen eller dens underklassetype. Du kan også binde parametertypen til et grensesnitt og passere implementeringene når du påkaller det, som i tilfellet med eksemplet ovenfor.

Hva skjer hvis du prøver å bruke noen annen type parameter?

myGenericClass myGen = new myGenericClass();

I tilfelle over vil du få en feil i kompileringstid som sier "Feil for ubundet: Type heltall er ikke et gyldig erstatning for typecasten av typen myGenericClass".

Flere avgrensede typer: I tilfelle av flere avgrensede typer kan vi binde parameterdatatypen til mer enn en type. For eksempel,

Class myGeneric()

I dette tilfellet kan du passere alle typer som utvider nummerklassen og implementerer kjørbart grensesnitt. Når du bruker flere avgrensede typer, er det imidlertid få ting som bør noteres:

  1. Vi kan ikke utvide mer enn en klasse om gangen.
  2. Vi kan utvide hvilket som helst antall grensesnitt om gangen, det er ingen grenser for grensesnitt.
  3. Klassenavnet skal alltid komme først etterfulgt av grensesnittnavnet, hvis ikke vil det føre til en kompilertidsfeil.

Type wildcards: De er representert med “?” - spørsmålstegn symbol. Den bruker to hovednøkkelord:

strekker seg (for å definere øvre grense) og super (for å definere nedre grenser).

For eksempel,

ArrayList al

Dette ArrayList-objektet "al" vil inneholde data fra type T og alle underklasser.

ArrayList al

Dette ArrayList-objektet "al" vil inneholde data fra type T og alle superklasser.

Fordeler med generikk i Java

1. Fleksibilitet : Generics gir koden vår fleksibilitet til å imøtekomme forskjellige datatyper ved hjelp av generiske klasser og metoder.

2. Vedlikehold og gjenbruk av kode: På grunn av generiske klasser og metoder trenger man ikke å skrive koden på nytt, i tilfelle endringer i krav på et senere tidspunkt som gjør koden enklere å vedlikeholde og gjenbruke.

3. Typesikkerhet: Gir typesikkerhet til innsamlingsrammen ved å definere datatypen samlingen kan inneholde på forhånd og eliminere eventuelle sjanser for feil på kjøretid på grunn av ClassCastException.

4. eliminere behovet for å typecast: Siden datatypene som er i samlingen allerede er bestemt, behøver man ikke å skrive den på tidspunktet for henting. Dette reduserer lengden på koden og reduserer også en koders innsats.

Generikere i Java-ferdigheter

For å jobbe med Generics, bør du være godt kjent med det grunnleggende i Java. Du bør forstå hvordan typekontroll og type casting fungerer. Grundig kunnskap om andre konsepter som metodebelastning, forholdet mellom foreldre- og barneklasser, grensesnitt og deres implementeringer er nødvendig. Å forstå forskjellen mellom primitive datatyper (systemdefinert datatype) og objekter (brukerdefinert datatype) er avgjørende når det gjelder å jobbe med innsamlingsrammen.

Hvorfor skal vi bruke Generics i Java?

Å bruke generiske data gjør koden vår mer vedlikeholdbar, da den reduserer behovet for å omskrive datatypespesifikk kode hver gang det endres i kravet. Ved å bruke generisk avgrenset type kan du begrense datatypen og samtidig gi fleksibiliteten til koden din ved å definere rekkevidden. Det er mindre sannsynlig at koden din mislykkes på et senere tidspunkt, da den gir trygghet for typen, noe som gjør koden din mindre utsatt for feil.

Omfang for generikk i Java

Generiske omfang er begrenset til å sammenstille tid. Det betyr at generikkonsept bare kan brukes på kompileringstidspunkt, men ikke på kjøretid. For eksempel,

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

Her er alle de ovennevnte fire utsagnene en og samme. De vil tillate tillegg av alle typer data til listeobjektet.

Konklusjon

Generics gjør kodingen enkel for en koder. Det reduserer sjansene for å møte ClassCastException ved kjøretid ved å tilby sterk typekontroll. Eliminerer behovet for avstøpning helt, noe som betyr at mindre kode må skrives. Det gir oss muligheten til å utvikle generiske algoritmer som er uavhengige av datatypen de jobber med.

Anbefalte artikler

Dette har vært en guide til Hva er Generics i Java ?. Her diskuterte vi ferdighetene, omfanget, arbeidet, forståelsen og fordelene ved generikk i Java. Du kan også gå gjennom andre foreslåtte artikler for å lære mer -

  1. Hva er felles gateway-grensesnitt
  2. Slik installerer du Java 8
  3. hva er soapUI
  4. Hva er JavaScript?
  5. Java Booleans