Generiske typer (Norsk)

En generisk type er en generisk klasse eller et grensesnitt som er parameterisert over typer. Følgende Box-klasse vil bli endret for å demonstrere konseptet.

En enkel Box-klasse

Begynn med å undersøke en ikke-generisk Box-klasse som fungerer på objekter av hvilken som helst type. Det trenger bare å tilby to metoder: sett, som legger til et objekt i boksen, og få, som henter det:

Siden metodene godtar eller returnerer et objekt, er du fri til å sende inn hva du vil , forutsatt at det ikke er en av de primitive typene. Det er ingen måte å verifisere hvordan klassen brukes på kompileringstidspunktet. En del av koden kan plassere et heltall i boksen og forvente å få heltall ut av det, mens en annen del av koden feilaktig kan passere i en streng, noe som resulterer i en kjøretidsfeil.

En generisk versjon av Box Class

En generisk klasse er definert med følgende format:

class name<T1, T2, ..., Tn> { /* ... */ }

For å oppdatere Box-klasse for å bruke generikk, du oppretter en generisk typedeklarasjon ved å endre koden «public class Box» til «public class Box < T > «. Dette introduserer typevariabelen, T, som kan brukes hvor som helst i klassen.

Med denne endringen blir Box-klassen:

Som du kan se, er alle forekomster av Object erstattet av T. En typevariabel kan være hvilken som helst ikke-primitiv type du angir: hvilken som helst klassetype, hvilken som helst grensesnitttype, hvilken som helst matritype eller til og med en annen type variabel.

Den samme teknikken kan brukes til å generiske grensesnitt.

Type Parameter Navngivningskonvensjoner

Etter konvensjon er typeparameternavn enkelt, store bokstaver. Dette står i skarp kontrast til variabelnavngivningskonvensjonene du allerede vet om, og med god grunn: Uten denne konvensjonen ville det være vanskelig å se forskjellen mellom en typevariabel og et vanlig klasse- eller grensesnittnavn.

De mest brukte typeparameternavnene er:

  • E – Element (brukt mye av Java Collections Framework)
  • K – Nøkkel
  • N – Antall
  • T – Type
  • V – Verdi
  • S, U, V etc. – 2., 3., 4. type

Du vil se disse navnene som brukes i Java SE API og resten av denne leksjonen.

Påkalle og installere en generisk type

For å referere til generisk Box-klasse innenfra koden din, må du utføre en generisk påkalling som erstatter T med en viss konkret verdi, for eksempel Heltall:

Box<Integer> integerBox;

Du kan tenke på en generisk innkalling som ligner på en vanlig metodeinnkallelse, men i stedet for å gi et argument til am ethod, sender du et typeargument – Heltall i dette tilfellet – til selve Box-klassen.

Type Parameter og Type Argument Terminology: Mange utviklere bruker begrepene «type parameter» og «type argument» om hverandre, men disse vilkårene er ikke de samme. Ved koding gir man typeargumenter for å lage en parameterisert type. Derfor er T i Foo < T > en type parameter og strengen i Foo < String > f er et typeargument. Denne leksjonen observerer denne definisjonen når du bruker disse begrepene.

Som enhver annen variabelerklæring, oppretter ikke denne koden faktisk et nytt Box-objekt. Den erklærer ganske enkelt at integerBox vil ha en referanse til en «Box of Integer», slik leses Box < Heltall >.

En påkallelse av en generisk type er vanligvis kjent som en parameterisert type.

For å instantiere denne klassen, bruk det nye nøkkelordet, som vanlig, men plasser < Heltall > mellom klassenavnet og parentesen:

Box<Integer> integerBox = new Box<Integer>();

Diamanten

I Java SE 7 og nyere kan du erstatte typeargumentene som kreves for å påkalle konstruktøren til en generisk klasse med et tomt sett med typeargumenter (< >) så lenge kompilatoren kan bestemme, eller utlede, typeargumentene fra konteksten. Dette paret av vinkelfester, < >, kalles uformelt diamanten. For eksempel kan du opprette en forekomst av Box < Heltall > med følgende utsagn:

Box<Integer> integerBox = new Box<>();

For mer informasjon om diamantnotasjon og typen inferens, se Type inferens.

Flere typeparametere

Som nevnt tidligere, en generisk klasse kan ha flere typeparametere.For eksempel den generiske OrderedPair-klassen, som implementerer det generiske Pair-grensesnittet:

Følgende utsagn skaper to instantiations av OrderedPair-klassen:

Koden, ny OrderedPair < Streng, heltall >, instantierer K som en streng og V som et heltall. Derfor er parametertypene til OrderedPair’s konstruktør henholdsvis String og Integer. På grunn av autoboksing er det gyldig å sende en streng og en int til klassen.

Som nevnt i The Diamond, fordi en Java-kompilator kan utlede K- og V-typene fra erklæringen OrderedPair < Streng, heltall >, disse utsagnene kan forkortes ved hjelp av diamantnotasjon:

OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);OrderedPair<String, String> p2 = new OrderedPair<>("hello", "world");

For å opprette et generisk grensesnitt, følg de samme konvensjonene som for å lage en generisk klasse.

Parameteriserte typer

OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));

Write a Comment

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *