Útmutató Guava reflexiós segédprogramjaihoz

1. Áttekintés

Ebben a cikkben megnézzük a Gujávafavisszaverődés API - ami határozottan sokoldalúbb a szokásos Java reflexiós API-hoz képest.

Majd használjuk Gujávafa generikus típusok futás közbeni rögzítésére, és ezeket jól fogjuk használni Meghívható is.

2. Általános típus rögzítése futás közben

A Java-ban a generikus típusok törlésével valósulnak meg. Ez azt jelenti, hogy az általános típusú információk csak fordításkor és futás közben állnak rendelkezésre - már nem állnak rendelkezésre.

Például, Lista, a generikus típusra vonatkozó információk futás közben törlődnek. Ebből a tényből kifolyólag nem biztonságos a generikus gyógyszerek megkerülése Osztály objektumok futás közben.

Végül két listát rendelhetünk ugyanahhoz a referenciához, amelyeknek különböző általános típusai vannak, ami nyilvánvalóan nem jó ötlet:

Lista stringList = Lists.newArrayList (); List intList = Lists.newArrayList (); logikai eredmény = stringList.getClass () .isAssignableFrom (intList.getClass ()); assertTrue (eredmény);

A típus törlése miatt a módszer isAssignableFrom () nem ismerheti a listák tényleges általános típusát. Alapvetően két típust hasonlít össze, amelyek csak a Lista a tényleges típusra vonatkozó információk nélkül.

A standard Java Reflection API segítségével felismerhetjük a módszerek és osztályok általános típusait. Ha van olyan módszerünk, amely a Lista, a reflexió segítségével megkaphatjuk a módszer visszatérési típusát - a ParameterizedType képviselve Lista.

A TypeToken osztály ezt a megoldást használja az általános típusok manipulálásának lehetővé tételére. Használhatjuk a TypeToken osztály, hogy rögzítsen egy tényleges típusú általános listát, és ellenőrizze, hogy valóban azonos hivatkozással lehet-e hivatkozni rájuk:

TypeToken stringListToken = új TypeToken() {}; TypeToken integerListToken = új TypeToken() {}; TypeToken numberTypeToken = új TypeToken() {}; assertFalse (stringListToken.isSubtypeOf (integerListToken)); assertFalse (számTypeToken.isSubtypeOf (integerListToken)); assertTrue (integerListToken.isSubtypeOf (numberTypeToken));

Csak a integerListToken típusú referenciához rendelhető nubmerTypeToken mert egy Egész szám osztály kiterjeszti a Szám osztály.

3. Bonyolult típusok rögzítése a használatával TypeToken

Tegyük fel, hogy általános paraméterezett osztályt akarunk létrehozni, és futás közben információval akarunk rendelkezni egy általános típusról. Készíthetünk olyan osztályt, amelynek van TypeToken mint az információ rögzítésére szolgáló mező:

absztrakt osztály ParametrizedClass {TypeToken type = new TypeToken (getClass ()) {}; }

Ezután az adott osztály egy példányának létrehozásakor az általános típus futás közben elérhető lesz:

ParametrizedClass parametrizedClass = new ParametrizedClass () {}; assertEquals (parametrizedClass.type, TypeToken.of (String.class));

Hozhatunk létre a TypeToken olyan komplex típusú, amely egynél több általános típussal rendelkezik, és futás közben szerez be információkat az egyes típusokról:

TypeToken funToken = új TypeToken() {}; TypeToken funResultToken = funToken .resolveType (Function.class.getTypeParameters () [1]); assertEquals (funResultToken, TypeToken.of (String.class));

Kapunk egy tényleges visszatérési típust Funkció, az egy Húr. Akár a bejegyzés típusát is megkaphatjuk a térképen:

TypeToken mapToken = new TypeToken() {}; TypeToken entrySetToken = mapToken .resolveType (Map.class.getMethod ("entrySet") .getGenericReturnType ()); assertEquals (entrySetToken, új TypeToken<>>() {}); 

Itt reflexiós módszert alkalmazunk getMethod () Java szabványos könyvtárból a metódus visszatérési típusának rögzítéséhez.

4. Meghívható

A Meghívható folyékonyan borítja java.lang.reflect.Method és java.lang.reflect.Constructor. Egyszerűbb API-t biztosít a standard Java tetején visszaverődés API. Tegyük fel, hogy van egy osztályunk, amelynek két nyilvános módszere van, és az egyik végleges:

class CustomClass {public void somePublicMethod () {} public final void notOverridablePublicMethod () {}}

Most vizsgáljuk meg a somePublicMethod () Guava API és Java szabvány használatával visszaverődés API:

Method módszer = CustomClass.class.getMethod ("somePublicMethod"); Invokable invokable = new TypeToken () {} .metódus (módszer); logikai isPublicStandradJava = Módosító.isPublic (method.getModifiers ()); logikai isPublicGuava = invokable.isPublic (); assertTrue (isPublicStandradJava); assertTrue (isPublicGuava);

E két változat között nincs sok különbség, de a módszer felülírhatóságának ellenőrzése a Java-ban valóban nem triviális feladat. Szerencsére a isOverridable () módszer a Meghívható osztály megkönnyíti:

Method módszer = CustomClass.class.getMethod ("notOverridablePublicMethod"); Invokable invokable = new TypeToken () {} .metódus (módszer); logikai isOverridableStandardJava = {! ) .getModifiers ()))); logikai isOverridableFinalGauava = invokable.isOverridable (); assertFalse (isOverridableStandardJava); assertFalse (isOverridableFinalGauava);

Látjuk, hogy még egy ilyen egyszerű művelethez is sok ellenőrzésre van szükség a standard használatával visszaverődés API. A Meghívható osztály elrejti ezt az egyszerűen használható és nagyon tömör API mögött.

5. Következtetés

Ebben a cikkben a Guava Reflection API-t néztük meg, és összehasonlítottuk a standard Java-val. Láttuk, hogyan lehet általános típusokat rögzíteni futás közben, és hogyan Meghívható osztály elegáns és könnyen használható API-t kínál a reflexiót használó kódhoz.

Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub projektben - ez egy Maven projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.