Vodič za uslužne programe Reflection u Guavi

1. Pregled

U ovom ćemo članku pogledati Guavaodraz API - koji je definitivno svestraniji u usporedbi sa standardnim Java refleksivnim API-jem.

Koristit ćemo Guava za hvatanje generičkih tipova tijekom izvođenja i dobro ćemo ih iskoristiti Nepozvan također.

2. Snimanje generičkog tipa tijekom izvođenja

U Javi se generički provodi s brisanjem tipova. To znači da su informacije o generičkom tipu dostupne samo u vrijeme sastavljanja, a za vrijeme izvođenja više nisu dostupne.

Na primjer, Popis, informacije o generičkom tipu brišu se tijekom izvođenja. Zbog te činjenice nije sigurno prenijeti generički Razred objekti u vrijeme izvođenja.

Na kraju bismo mogli dodijeliti dva popisa koji imaju različite generičke tipove istoj referenci, što očito nije dobra ideja:

Popis stringList = Lists.newArrayList (); Popis intList = Lists.newArrayList (); boolean rezultat = stringList.getClass () .isAssignableFrom (intList.getClass ()); assertTrue (rezultat);

Zbog brisanja tipa, metoda isAssignableFrom () ne mogu znati stvarni generički tip popisa. U osnovi uspoređuje dvije vrste koje su samo a Popis bez ikakvih podataka o stvarnom tipu.

Korištenjem standardnog Java refleksivnog API-ja možemo otkriti generičke tipove metoda i klasa. Ako imamo metodu koja vraća a Popis, pomoću refleksije možemo dobiti povratnu vrstu te metode - a ParameterizedType zastupajući Popis.

The TypeToken klasa koristi ovo rješenje kako bi omogućila manipulaciju generičkim tipovima. Možemo koristiti TypeToken klase za hvatanje stvarne vrste generičkog popisa i provjeru mogu li se na njih zaista uputiti istom referencom:

TypeToken stringListToken = novi TypeToken() {}; TypeToken integerListToken = novi TypeToken() {}; TypeToken numberTypeToken = novi TypeToken() {}; assertFalse (stringListToken.isSubtypeOf (integerListToken)); assertFalse (numberTypeToken.isSubtypeOf (integerListToken)); assertTrue (integerListToken.isSubtypeOf (numberTypeToken));

Samo integerListToken može se dodijeliti referenci tipa nubmerTypeToken jer an Cijeli broj razred produžuje a Broj razred.

3. Snimanje složenih vrsta pomoću TypeToken

Recimo da želimo stvoriti generičku parametriziranu klasu i želimo imati informacije o generičkom tipu tijekom izvođenja. Možemo stvoriti razred koji ima TypeToken kao polje za hvatanje tih podataka:

apstraktna klasa ParametrizedClass {TypeToken type = new TypeToken (getClass ()) {}; }

Tada će, prilikom stvaranja instance te klase, generički tip biti dostupan za vrijeme izvođenja:

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

Također možemo stvoriti i TypeToken složenog tipa koji ima više od jednog generičkog tipa i dohvaćaju informacije o svakom od tih tipova tijekom izvođenja:

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

Dobivamo stvarni tip povrata za Funkcija, to je Niz. Na karti možemo dobiti čak i vrstu unosa:

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

Ovdje se služimo metodom refleksije getMethod () iz standardne biblioteke Java za hvatanje tipa povratka metode.

4. Nepozvan

The Nepozvan je tečni omot od java.lang.reflect.Method i java.lang.reflect.Constructor. Pruža jednostavniji API povrh standardne Jave odraz API. Recimo da imamo razred koji ima dvije javne metode i jedna od njih je konačna:

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

Sada ispitajmo somePublicMethod () koristeći Guava API i Java standard odraz API:

Metoda metode = CustomClass.class.getMethod ("somePublicMethod"); Nepozivljiv dozivan = novi TypeToken () {} .metoda (metoda); logička isPublicStandradJava = Modifikator.isPublic (method.getModifiers ()); logička isPublicGuava = invokable.isPublic (); assertTrue (isPublicStandradJava); assertTrue (isPublicGuava);

Između ove dvije varijante nema velike razlike, ali provjera je li metoda nadrediva uistinu je ne trivijalan zadatak u Javi. Srećom, isOverridable () metoda iz Nepozvan klasa olakšava:

Metoda metode = CustomClass.class.getMethod ("notOverridablePublicMethod"); Nepozivljiv dozivan = novi TypeToken () {} .metoda (metoda); boolean isOverridableStandardJava = (! (Modifier.isFinal (method.getModifiers ()) || Modifier.isPrivate (method.getModifiers ()) || Modifier.isStatic (method.getModifiers ()) || Modifier.isFinal (method.getDeclaringClass) ) .getModifiers ()))); boolean isOverridableFinalGauava = invokable.isOverridable (); assertFalse (isOverridableStandardJava); assertFalse (isOverridableFinalGauava);

Vidimo da čak i za tako jednostavnu operaciju treba puno provjera koristeći standard odraz API. The Nepozvan class to skriva iza API-ja koji je jednostavan za upotrebu i vrlo sažet.

5. Zaključak

U ovom smo članku gledali API za odraz Guave i usporedili ga sa standardnom Javom. Vidjeli smo kako hvatanje generičkih tipova tijekom izvođenja i kako Nepozvan klasa pruža elegantan i jednostavan API za kôd koji koristi refleksiju.

Provedbu svih ovih primjera i isječaka koda možete pronaći u projektu GitHub - ovo je Maven projekt, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.


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