Szuper típusú tokenek a Java Generics-ben
1. Áttekintés
Ebben az oktatóanyagban megismerkedünk a szuper típusú tokenekkel, és megismerhetjük, hogyan segíthetnek nekünk az általános típusú információk futás közbeni megőrzésében.
2. A törlés
Néha egy adott típusú információt át kell adnunk egy módszerhez. Például itt azt várjuk, hogy Jackson a JSON bájt tömböt konvertálja a Húr:
bájt [] data = // json lekérése valahonnan String json = objectMapper.readValue (adatok, String.osztály);
Ezt az elvárást szó szerinti osztályjelen keresztül kommunikáljuk, ebben az esetben a Karakterlánc.osztály.
Ugyanakkor nem állíthatjuk be ugyanolyan elvárást az általános típusok esetében:
Map json = objectMapper.readValue (adatok, Map.class); // nem állít össze
A Java a fordítás során törli az általános típusú információkat. Ebből kifolyólag, Az általános típusú paraméterek csupán a forráskód tárgyai, és futás közben nem lesznek jelen.
2.1. Reification
Technikailag elmondható, hogy az általános típusokat a Java nem igazolja újra. A programozási nyelv terminológiájában amikor egy típus futás közben van, akkor azt mondjuk, hogy a típus újra érvényesül.
A Java újratervezett típusai a következők:
- Egyszerű primitív típusok, mint pl hosszú
- Nem általános absztrakciók, mint pl Húr vagy Futható
- Nyers típusok, mint pl Lista vagy HashMap
- Általános típusok, amelyekben minden típus nem korlátozott helyettesítő karakter, mint pl Lista vagy HashMap
- Egyéb újrarefinált típusú tömbök, például Karakterlánc [], int [], Lista [], vagy Térkép[]
Következésképpen nem használhatunk ilyesmit Térkép.osztály mert a Térkép nem reifikált típus.
3. Szuper típusú token
Mint kiderült, kihasználhatjuk a Java névtelen belső osztályainak erejét, hogy megőrizzük a típusinformációkat a fordítási idő alatt:
public abstract class TypeReference {private final Type type; public TypeReference () {Type superclass = getClass (). getGenericSuperclass (); type = ((ParameterizedType) szuperosztály) .getActualTypeArguments () [0]; } public type getType () {return type; }}
Ez az osztály absztrakt, ezért csak alosztályokat vezethetünk le belőle.
Például létrehozhatunk egy névtelen belső:
TypeReference
A kivitelező a következő lépéseket teszi a típusinformációk megőrzése érdekében:
- Először megkapja az adott szuper osztály általános metaadatait ehhez a példányhoz - ebben az esetben a generikus szuperosztály TypeReference
- Ezután megkapja és eltárolja az általános szuperosztály tényleges típusparaméterét - ebben az esetben az lenne Térkép
Ez a megközelítés a generikus típusú információk megőrzésére általában néven ismert szuper típusú token:
TypeReference token = új TypeReference() {}; Típus type = token.getType (); assertEquals ("java.util.Map", type.getTypeName ()); Type [] typeArguments = ((ParameterizedType) type) .getActualTypeArguments (); assertEquals ("java.lang.String", typeArguments [0] .getTypeName ()); assertEquals ("java.lang.Integer", typeArguments [1] .getTypeName ());
Szuper típusú tokenek használatával tudjuk, hogy a tárolótípus az Térkép, és típusparaméterei is Húr és Egész szám.
Ez a minta annyira híres, hogy a Jackson-könyvtáraknak és a Spring-hez hasonló keretrendszereknek saját megvalósításaik vannak. JSON objektum elemzése a Térkép úgy érhető el, hogy meghatározzuk az adott típust egy szuper típusú tokennel:
TypeReference token = új TypeReference() {}; Map json = objectMapper.readValue (adatok, token);
4. Következtetés
Ebben az oktatóanyagban megtanultuk, hogyan használhatunk szuper típusú tokeneket az általános típusú információk futás közbeni megőrzésére.
Szokás szerint az összes példa elérhető a GitHubon.