Tokeni super tipa u Java Generics

1. Pregled

U ovom uputstvu upoznat ćemo se sa tokenima super tipa i vidjeti kako nam mogu pomoći u očuvanju informacija o generičkom tipu tijekom izvođenja.

2. Brisanje

Ponekad moramo neku metodu prenijeti informacije o određenom tipu. Na primjer, ovdje očekujemo od Jacksona da pretvori JSON bajt polje u Niz:

byte [] data = // dohvatiti json odnekud String json = objectMapper.readValue (podaci, String.class);

Ovo očekivanje prenosimo putem literalnog tokena klase, u ovom slučaju, String.razred.

Međutim, ne možemo jednako lako postaviti isto očekivanje za generičke tipove:

Map json = objectMapper.readValue (podaci, Map.class); // neće se sastaviti

Java briše informacije o generičkom tipu tijekom kompilacije. Stoga, parametri generičkog tipa samo su artefakt izvornog koda i neće biti prisutni tijekom izvođenja.

2.1. Reifikacija

Tehnički gledano, generički tipovi nisu reificirani u Javi. U terminologiji programskog jezika, kada je tip prisutan u vrijeme izvođenja, kažemo da je taj tip reificiran.

Ponovno utvrđeni tipovi u Javi su sljedeći:

  • Jednostavni primitivni tipovi kao što su dugo
  • Negeneričke apstrakcije kao što su Niz ili Izvodljivo
  • Sirove vrste poput Popis ili HashMap
  • Generički tipovi kod kojih su sve vrste neograničeni zamjenski znakovi kao što su Popis ili HashMap
  • Nizovi drugih reificiranih tipova kao što su Niz [], int [], popis [], ili Karta[]

Slijedom toga, ne možemo koristiti nešto poput Karta.razred jer Karta nije reificirani tip.

3. Super tip žetona

Ispostavilo se, možemo iskoristiti snagu anonimnih unutarnjih klasa u Javi da sačuvamo podatke o tipu tijekom vremena kompajliranja:

javna apstraktna klasa TypeReference {privatni konačni Type type; public TypeReference () {Type superclass = getClass (). getGenericSuperclass (); type = ((ParameterizedType) superclass) .getActualTypeArguments () [0]; } javni tip getType () {povratni tip; }}

Ova je klasa apstraktna, pa iz nje možemo izvoditi samo podrazrede.

Na primjer, možemo stvoriti anonimni unutarnji:

TypeReference token = novi TypeReference() {};

Konstruktor čini sljedeće korake kako bi sačuvao informacije o tipu:

  • Prvo, dobiva generičke metarazrede superrazreda za ovaj određeni primjer - u ovom je slučaju generički superrazred TypeReference
  • Zatim dobiva i pohranjuje stvarni parametar tipa za generičku superklasu - u ovom bi slučaju to bio Karta

Ovaj pristup očuvanju informacija o generičkom tipu obično je poznat kao token super tipa:

TypeReference token = novi TypeReference() {}; Upišite type = token.getType (); assertEquals ("java.util.Map", type.getTypeName ()); Tip [] typeArguments = (((ParameterizedType) tip) .getActualTypeArguments (); assertEquals ("java.lang.String", typeArguments [0] .getTypeName ()); assertEquals ("java.lang.Integer", typeArguments [1] .getTypeName ());

Korištenjem tokena super tipa znamo da je tip spremnika Karta, a također su i njegovi parametri tipa Niz i Cijeli broj.

Ovaj je obrazac toliko poznat da ga knjižnice poput Jacksona i okviri poput Springa imaju vlastite implementacije. Raščlanjivanje JSON objekta u Karta može se postići definiranjem tog tipa s tokenom super tipa:

TypeReference token = novi TypeReference() {}; Mapa json = objectMapper.readValue (podaci, token);

4. Zaključak

U ovom smo tutorijalu naučili kako možemo koristiti tokene super tipa za očuvanje informacija o generičkom tipu tijekom izvođenja.

Kao i obično, svi su primjeri dostupni na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found