Vodič za Java Reflection

1. Pregled

U ovom ćemo članku istraživati ​​Java refleksiju, koja nam omogućuje inspekciju ili / i modificiranje runtime atributa klasa, sučelja, polja i metoda. To posebno dobro dođe kada im ne znamo imena u vrijeme sastavljanja.

Uz to, možemo instancirati nove objekte, pozvati metode i dobiti ili postaviti vrijednosti polja pomoću refleksije.

2. Postavljanje projekta

Da bismo koristili Java refleksiju, ne trebamo uključiti nikakve posebne staklenke, bilo koja posebna konfiguracija ili Mavenove ovisnosti. JDK se isporučuje s grupom klasa koje su povezane u java.lang.reflect paket posebno za tu svrhu.

Dakle, sve što trebamo učiniti je izvršiti sljedeći uvoz u naš kod:

uvoz java.lang.reflect. *;

i dobro je krenuti.

Da bismo dobili pristup klasi, metodi i informacijama o polju instance nazivamo getClass metoda koja vraća predstavljanje klase vremena izvođenja objekta. Povratak razred object pruža metode za pristup informacijama o klasi.

3. Jednostavan primjer

Kako bismo smočili noge, pogledat ćemo vrlo osnovni primjer koji pregledava polja jednostavnog Java objekta tijekom izvođenja.

Stvorimo jednostavan Osoba razred sa samo Ime i dob polja i nikakvih metoda. Evo klase Osoba:

javni razred Osoba {ime privatnog niza; privatno int doba; }

Sada ćemo koristiti Javinu refleksiju kako bismo otkrili imena svih polja ove klase. Da bismo uvažili moć refleksije, konstruirat ćemo a Osoba objekt i koristite Object kao referentnu vrstu:

@Test javna praznina givenObject_whenGetsFieldNamesAtRuntime_thenCorrect () {Object person = new Person (); Polje [] polja = person.getClass (). GetDeclaredFields (); Navesti stvarnaPoljaName = getFieldNames (polja); assertTrue (Arrays.asList ("name", "age") .containsAll (actualFieldNames)); }

Ovaj test pokazuje nam da smo u mogućnosti dobiti niz FIeld predmeti iz našeg osoba objekta, čak i ako je referenca na objekt roditeljska vrsta tog objekta.

U gornjem primjeru zanimala su nas samo imena tih polja, ali još se puno toga može učiniti, a daljnje primjere za to vidjet ćemo u sljedećim odjeljcima.

Primijetite kako koristimo pomoćnu metodu za izdvajanje stvarnih imena polja, to je vrlo osnovni kod:

privatni statički popis getFieldNames (polja [] polja) {List fieldNames = novi ArrayList (); za (Polje polja: polja) fieldNames.add (field.getName ()); return fieldNames; }

4. Slučajevi upotrebe Java Reflection

Prije nego što nastavimo s različitim značajkama Java refleksije, razgovarat ćemo o nekim uobičajenim uporabama koje bismo mogli naći za nju. Java refleksija je izuzetno moćna i može vam vrlo dobro doći na više načina.

Na primjer, u mnogim slučajevima imamo konvenciju imenovanja tablica baze podataka. Možemo odlučiti dodati dosljednost tako što ćemo unaprijed fiksirati nazive tablica s tbl_, takav da se zove tablica s podacima o studentima tbl_student_data.

U takvim slučajevima objekt Java koji sadrži podatke učenika možemo nazvati kao Student ili Podaci o studentu. Tada pomoću CRUD paradigme imamo po jednu ulaznu točku za svaku operaciju takvu da Stvoriti operacije dobivaju samo Objekt parametar.

Zatim koristimo refleksiju za dohvaćanje imena predmeta i imena polja. U ovom trenutku te podatke možemo preslikati u DB tablicu i dodijeliti vrijednosti polja objekta odgovarajućim imenima DB polja.

5. Pregled Java klasa

U ovom ćemo odjeljku istražiti najvažniju komponentu u API-ju za odražavanje Java. Objekti Java klase, kao što smo ranije spomenuli, daju nam pristup internim detaljima bilo kojeg objekta.

Ispitat ćemo interne podatke poput naziva klase objekta, modifikatora, polja, metoda, implementiranih sučelja itd.

5.1. Spremiti se

Da bismo čvrsto shvatili API refleksije, primijenjen na Java klase i imali primjere s raznolikošću, stvorit ćemo sažetak Životinja klasa koja provodi Jelo sučelje. Ovo sučelje definira prehrambeno ponašanje bilo kojeg betona Životinja objekt koji stvaramo.

Dakle, prvo, ovdje je Jelo sučelje:

javno sučelje Eating {String eats (); }

a zatim beton Životinja provedba Jelo sučelje:

javna apstraktna klasa Animal implementira Jelo {public static String CATEGORY = "domestic"; privatni naziv niza; zaštićeni sažetak String getSound (); // konstruktor, izostavljeni standardni getteri i postavljači}

Stvorimo i drugo sučelje zvano Kretanje koji opisuje kako se životinja kreće:

javno sučelje Locomotion {String getLocomotion (); }

Sada ćemo stvoriti konkretnu klasu tzv Jarac koja se proteže Životinja i provodi Kretanje. Budući da superklasa provodi Jelo, Jarac morat će implementirati i metode tog sučelja:

javna klasa Goat proširuje Animal implementira Locomotion {@Override protected String getSound () {return "bleat"; } @Override public String getLocomotion () {return "šetnje"; } @Override public String eats () {return "trava"; } // konstruktor izostavljen}

Od ovog trenutka nadalje, koristit ćemo Java refleksiju za inspekciju aspekata Java objekata koji se pojavljuju u gornjim klasama i sučeljima.

5.2. Imena razreda

Krenimo od dobivanja imena predmeta iz Razred:

@Test javna praznina givenObject_whenGetsClassName_thenCorrect () {Objekt jarac = novi jarac ("jarac"); Klasa klazz = goat.getClass (); assertEquals ("Koza", clazz.getSimpleName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getCanonicalName ()); }

Imajte na umu da getSimpleName metoda Razred vraća osnovni naziv objekta kakav bi se pojavio u njegovoj deklaraciji. Tada ostale dvije metode vraćaju potpuno kvalificirano ime klase, uključujući deklaraciju paketa.

Pogledajmo i kako možemo stvoriti objekt Jarac klase ako znamo samo njegovo potpuno kvalificirano ime klase:

@Test javna praznina givenClassName_whenCreatesObject_thenCorrect () {Class clazz = Class.forName ("com.baeldung.reflection.Goat"); assertEquals ("Koza", clazz.getSimpleName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getCanonicalName ()); }

Primijetite da naziv koji prenosimo na statički zaName metoda treba sadržavati podatke o paketu. U suprotnom ćemo dobiti a ClassNotFoundException.

5.3. Modifikatori klase

Modifikatore koji se koriste u klasi možemo odrediti pozivom na getModifiers metoda koja vraća an Cijeli broj. Svaki je modifikator bit oznake koji je ili postavljen ili obrisan.

The java.lang.reflect.Modifier klasa nudi statičke metode koje analiziraju vraćeno Cijeli broj za prisutnost ili odsutnost određenog modifikatora.

Potvrdimo modifikatore nekih klasa koje smo gore definirali:

@Test javna praznina givenClass_whenRecognisesModifiers_thenCorrect () {Class goatClass = Class.forName ("com.baeldung.reflection.Goat"); Klasa animalClass = Class.forName ("com.baeldung.reflection.Animal"); int goatMods = goatClass.getModifiers (); int animalMods = animalClass.getModifiers (); assertTrue (Modifier.isPublic (goatMods)); assertTrue (Modifier.isAbstract (animalMods)); assertTrue (Modifier.isPublic (animalMods)); }

U mogućnosti smo pregledati modifikatore bilo koje klase koja se nalazi u staklenci knjižnice koju uvozimo u naš projekt.

U većini slučajeva možda ćemo trebati koristiti zaName pristup, a ne cjelovitu instanciju, jer bi to bio skup postupak u slučaju teških klasa memorije.

5.4. Informacije o paketu

Korištenjem Java refleksije također možemo dobiti informacije o paketu bilo koje klase ili objekta. Ti su podaci povezani u Paket klase koja se vraća pozivom na getPackage metoda na objektu klase.

Pokrenimo test za dohvaćanje naziva paketa:

@Test javna praznina givenClass_whenGetsPackageInfo_thenCorrect () {Jarac koza = novi jarac ("jarac"); Razred goatClass = goat.getClass (); Paket pkg = goatClass.getPackage (); assertEquals ("com.baeldung.reflection", pkg.getName ()); }

5.5. Super klasa

Također možemo dobiti superklasu bilo koje Java klase pomoću Java refleksije.

U mnogim slučajevima, posebno dok koristimo klase knjižnice ili ugrađene Javine klase, možda unaprijed ne znamo superklasu objekta koji koristimo, ovaj će pododjeljak pokazati kako doći do ovih podataka.

Pa krenimo dalje i odredimo superklasu od Jarac. Dodatno, to također pokazujemo java.lang.String razred je podrazred od java.lang.Object razred:

@Test javna praznina givenClass_whenGetsSuperClass_thenCorrect () {Jarac koza = novi jarac ("jarac"); Niz str = "bilo koji niz"; Razred goatClass = goat.getClass (); Klasa goatSuperClass = goatClass.getSuperclass (); assertEquals ("Animal", goatSuperClass.getSimpleName ()); assertEquals ("Objekt", str.getClass (). getSuperclass (). getSimpleName ()); }

5.6. Implementirana sučelja

Korištenjem Java refleksije također smo u mogućnosti dobiti popis sučelja koja je implementirala zadana klasa.

Dohvatimo tipove klasa sučelja koja implementira Jarac razred i Životinja sažetak klase:

@Test javna praznina givenClass_whenGetsImplementedInterfaces_thenCorrect () {Class goatClass = Class.forName ("com.baeldung.reflection.Goat"); Klasa animalClass = Class.forName ("com.baeldung.reflection.Animal"); Klasa [] goatInterfaces = goatClass.getInterfaces (); Klasa [] animalInterfaces = animalClass.getInterfaces (); assertEquals (1, goatInterfaces.length); assertEquals (1, animalInterfaces.length); assertEquals ("Locomotion", goatInterfaces [0] .getSimpleName ()); assertEquals ("Jelo", animalInterfaces [0] .getSimpleName ()); }

Primijetite iz tvrdnji da svaka klasa implementira samo jedno sučelje. Pregledavajući nazive ovih sučelja, nalazimo to Jarac provodi Kretanje i Životinja provodi Jelo, baš kao što se pojavljuje u našem kodu.

Možda ste to primijetili Jarac je podrazred apstraktne klase Životinja i provodi metodu sučelja jede (), onda, Jarac također provodi Jelo sučelje.

Stoga je vrijedno napomenuti da samo ona sučelja koja klasa izričito deklarira kao implementirana s provodi ključna riječ pojavljuje se u vraćenom nizu.

Pa čak i ako klasa implementira metode sučelja jer njena superklasa implementira to sučelje, ali potklasa to sučelje izravno ne deklarira provodi ključna riječ, tada se to sučelje neće pojaviti u nizu sučelja.

5.7. Konstruktori, metode i polja

Uz Java refleksiju, možemo pregledati konstruktore klase bilo kojeg objekta kao i metode i polja.

Kasnije ćemo moći vidjeti dublje inspekcije svake od ovih komponenata klase, ali za sada je dovoljno samo dobiti njihova imena i usporediti ih s onim što očekujemo.

Pogledajmo kako doći do konstruktora Jarac razred:

@Test javna praznina givenClass_whenGetsConstructor_thenCorrect () {Class goatClass = Class.forName ("com.baeldung.reflection.Goat"); Konstruktor [] konstruktori = goatClass.getConstructors (); assertEquals (1, constructors.length); assertEquals ("com.baeldung.reflection.Goat", konstruktori [0] .getName ()); }

Također možemo pregledati polja Životinja razred tako:

@Test javna praznina givenClass_whenGetsFields_thenCorrect () {Class animalClass = Class.forName ("com.baeldung.reflection.Animal"); Polje [] polja = animalClass.getDeclaredFields (); Popis stvarnih polja = getFieldNames (polja); assertEquals (2, actualFields.size ()); assertTrue (actualFields.containsAll (Arrays.asList ("name", "CATEGORY"))); }

Baš kao što možemo pregledati metode Životinja razred:

@Test javna praznina givenClass_whenGetsMethods_thenCorrect () {Klasa animalClass = Class.forName ("com.baeldung.reflection.Animal"); Metoda [] metode = animalClass.getDeclaredMethods (); Navesti stvarneMetode = getMethodNames (metode); assertEquals (4, actualMethods.size ()); assertTrue (actualMethods.containsAll (Arrays.asList ("getName", "setName", "getSound"))); }

Baš kao getFieldNames, dodali smo pomoćnu metodu za dohvaćanje imena metoda iz niza Metoda objekti:

privatni statički popis getMethodNames (Method [] metode) {List methodNames = new ArrayList (); za (Metod metode: metode) methodNames.add (method.getName ()); return methodNames; }

6. Pregled konstruktora

Uz razmišljanje o Javi možemo pregledati konstruktore bilo koje klase i čak stvoriti objekte klase u vrijeme izvođenja. To omogućuje java.lang.reflect.Constructor razred.

Ranije smo samo gledali kako dobiti niz Konstruktor objekata iz kojih smo mogli dobiti imena konstruktora.

U ovom ćemo se dijelu usredotočiti na to kako dohvatiti određene konstruktore. U Javi, kao što znamo, nema dva konstruktora klase koja dijele potpuno isti potpis metode. Dakle, iskoristit ćemo ovu jedinstvenost da od mnogih dobijemo jedan konstruktor.

Da bismo uvažili značajke ove klase, stvorit ćemo Ptica podrazred od Životinja s tri konstruktora. Nećemo provoditi Kretanje tako da možemo odrediti to ponašanje koristeći argument konstruktora, da bismo dodali još više raznolikosti:

javna klasa Bird produžuje životinje {privatne booleovske šetnje; public Bird () {super ("ptica"); } javna ptica (ime niza, logičke šetnje) {super (ime); setWalks (šetnje); } javna ptica (ime niza) {super (ime); } javne logičke šetnje () {povratne šetnje; } // standardni postavljači i nadjačane metode}

Potvrdimo pomoću refleksije da ova klasa ima tri konstruktora:

@Test javna praznina givenClass_whenGetsAllConstructors_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Konstruktor [] konstruktori = birdClass.getConstructors (); assertEquals (3, constructors.length); }

Dalje, dohvatit ćemo svaki konstruktor za Ptica klase prosljeđivanjem tipova klasa parametara konstruktora u deklariranom redoslijedu:

@Test javna praznina givenClass_whenGetsEachConstructorByParamTypes_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Konstruktor cons1 = birdClass.getConstructor (); Konstruktor cons2 = birdClass.getConstructor (String.class); Konstruktor cons3 = birdClass.getConstructor (String.class, boolean.class); }

Nema potrebe za tvrdnjom, jer kada konstruktor s danim vrstama parametara u danom redoslijedu ne postoji, dobit ćemo NoSuchMethodException i test automatski neće uspjeti.

U posljednjem ćemo testu vidjeti kako instancirati objekte u vrijeme izvođenja, a davati njihove parametre:

@Test javna praznina givenClass_whenInstantiatesObjectsAtRuntime_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Konstruktor cons1 = birdClass.getConstructor (); Konstruktor cons2 = birdClass.getConstructor (String.class); Konstruktor cons3 = birdClass.getConstructor (String.class, boolean.class); Ptica ptica1 = (Ptica) cons1.newInstance (); Ptica ptica2 = (Ptica) cons2.newInstance ("Ptica tkalja"); Ptica ptica3 = (Ptica) cons3.newInstance ("golubica", istina); assertEquals ("ptica", bird1.getName ()); assertEquals ("ptica tkalja", bird2.getName ()); assertEquals ("golubica", bird3.getName ()); assertFalse (bird1.walks ()); assertTrue (bird3.walks ()); }

Instanciramo objekte klase pozivajući newInstance metoda Konstruktor klase i predaje potrebnih parametara po deklariranom redoslijedu. Zatim smo rezultat prebacili na traženu vrstu.

Također je moguće nazvati zadani konstruktor pomoću Class.newInstance () metoda. Međutim, ova je metoda zastarjela od Jave 9 i ne bismo je trebali koristiti u modernim Java projektima.

Za ptica1, koristimo zadani konstruktor koji iz našeg Ptica kod, automatski postavlja ime na pticu i to potvrđujemo testom.

Zatim instanciramo ptica2 samo s imenom i testom, imajte na umu da kad ne postavimo ponašanje kretanja jer ono po defaultu nije lažno, kao što se vidi u posljednje dvije tvrdnje.

7. Pregled polja

Prije smo pregledavali samo imena polja, u ovom smo odjeljku mi ćemo pokazati kako sedobiti i postaviti njihove vrijednosti tijekom izvođenja.

Dvije su glavne metode korištene za inspekciju polja klase u vrijeme izvođenja: getFields () i getField (fieldName).

The getFields () metoda vraća sva dostupna javna polja predmetne klase. Vratit će sva javna polja u razredu i svim superrazredima.

Na primjer, kada ovu metodu pozovemo na Ptica klase, dobit ćemo samo KATEGORIJA polje svoje superrazrede, Životinja, budući da Ptica sama ne prijavljuje nikakva javna polja:

@Test javna praznina givenClass_whenGetsPublicFields_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Polje [] polja = birdClass.getFields (); assertEquals (1, polja.duljina); assertEquals ("KATEGORIJA", polja [0] .getName ()); }

Ova metoda također ima varijantu koja se naziva getField koji vraća samo jedan Polje objekt uzimajući ime polja:

@Test javna praznina givenClass_whenGetsPublicFieldByName_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Polje polja = birdClass.getField ("KATEGORIJA"); assertEquals ("KATEGORIJA", field.getName ()); }

Nismo u mogućnosti pristupiti privatnim poljima deklariranim u superklasama i neprijavljenim u podređenoj klasi. Zbog toga nismo u mogućnosti pristupiti Ime polje.

Međutim, možemo pregledati privatna polja deklarirana u klasi s kojom imamo posla pozivanjem getDeclaredFields metoda:

@Test javna praznina givenClass_whenGetsDeclaredFields_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Polje [] polja = birdClass.getDeclaredFields (); assertEquals (1, polja.duljina); assertEquals ("šetnje", polja [0] .getName ()); }

Možemo se poslužiti i njegovom drugom varijantom u slučaju da znamo naziv polja:

@Test javna praznina givenClass_whenGetsFieldsByName_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Polje polja = birdClass.getDeclaredField ("šetnje"); assertEquals ("šetnje", field.getName ()); }

Ako pogrešno dobijemo ime polja ili upišemo u postojeće polje, dobit ćemo a NoSuchFieldException.

Dobivamo vrstu polja kako slijedi:

@Test javna praznina givenClassField_whenGetsType_thenCorrect () {Polje polja = Class.forName ("com.baeldung.reflection.Bird") .getDeclaredField ("šetnje"); Klasa fieldClass = field.getType (); assertEquals ("boolean", fieldClass.getSimpleName ()); }

Dalje ćemo pogledati kako pristupiti vrijednostima polja i mijenjati ih. Da bismo mogli dobiti vrijednost polja, a kamoli ga postaviti, prvo moramo postaviti da je dostupno pozivom setAccessible metoda na Polje objekt i proslijedi boolean pravi tome:

@Test javna praznina givenClassField_whenSetsAndGetsValue_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Ptica ptica = (Ptica) birdClass.getConstructor (). NewInstance (); Polje polja = birdClass.getDeclaredField ("šetnje"); field.setAccessible (true); assertFalse (field.getBoolean (ptica)); assertFalse (bird.walks ()); field.set (ptica, istina); assertTrue (field.getBoolean (ptica)); assertTrue (bird.walks ()); }

U gore navedenom testu utvrđujemo da je zaista vrijednost šetnje polje je false prije nego što ga postavite na true.

Primijetite kako koristimo Polje objekt za postavljanje i dobivanje vrijednosti tako što će mu se proslijediti instanca klase s kojom imamo posla i eventualno nova vrijednost koju želimo da polje ima u tom objektu.

Treba imati na umu jednu važnu stvar Polje objekt je da kada se deklarira kao javna statika, tada nam ne treba instanca klase koja ih sadrži, možemo samo proći null na njegovo mjesto i dalje dobivajte zadanu vrijednost polja, ovako:

@Test javna praznina givenClassField_whenGetsAndSetsWithNull_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Polje polja = birdClass.getField ("KATEGORIJA"); field.setAccessible (true); assertEquals ("domaći", field.get (null)); }

8. Inspekcija metoda

U prethodnom primjeru koristili smo refleksiju samo za pregled naziva metoda. Međutim, Java refleksija je moćnija od toga.

Uz razmišljanje o Javi možemo pozvati metode na vrijeme izvođenja i proslijedite im potrebne parametre, baš kao i mi za konstruktore. Slično tome, također se možemo pozvati na preopterećene metode specificiranjem vrsta parametara svake od njih.

Kao i polja, postoje dvije glavne metode koje koristimo za dohvaćanje metoda klase. The getMethods metoda vraća niz svih javnih metoda klase i superklasa.

To znači da ovom metodom možemo dobiti javne metode java.lang.Object razred poput toString, hashCode, i notifyAll:

@Test javna praznina givenClass_whenGetsAllPublicMethods_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Metoda [] metode = birdClass.getMethods (); PopisNamena metoda = getMethodNames (metode); assertTrue (methodNames.containsAll (Arrays .asList ("jednako", "notifyAll", "hashCode", "šetnje", "jede", "toString"))); }

Moramo koristiti samo javne metode klase koja nas zanima getDeclaredMethods metoda:

@Test javna praznina givenClass_whenGetsOnlyDeclaredMethods_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Navesti stvarneMetodeNames = getMethodNames (birdClass.getDeclaredMethods ()); Lista očekivanihMetodaName = Nizovi .asList ("setWalks", "šetnje", "getSound", "jede"); assertEquals (očekivanaMetodaName.size (), stvarnaMetodaName.size ()); assertTrue (očekuje seMetodaName.sadržiAll (stvarnaMetodaName)); assertTrue (actualMethodNames.containsAll (očekuje seMetoda)); }

Svaka od ovih metoda ima pojedinačnu varijaciju koja vraća jednu Metoda objekt čije ime znamo:

@Test javna praznina givenMethodName_whenGetsMethod_thenCorrect () baca iznimku {Bird bird = new Bird (); Metoda walksMethod = bird.getClass (). GetDeclaredMethod ("šetnje"); Metoda setWalksMethod = bird.getClass (). GetDeclaredMethod ("setWalks", boolean.class); assertTrue (walksMethod.canAccess (ptica)); assertTrue (setWalksMethod.canAccess (ptica)); }

Primijetite kako dohvaćamo pojedinačne metode i odredimo koje vrste parametara uzimaju. Oni koji ne uzimaju tipove parametara dohvaćaju se s praznim argumentom varijable, ostavljajući nam samo jedan argument, naziv metode.

Dalje, pokazat ćemo kako pozvati metodu u vrijeme izvođenja. Zadano znamo da šetnje atribut Ptica razred je lažno, želimo ga nazvati setWalks metodu i postavite na pravi:

@Test javna praznina givenMethod_whenInvokes_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Ptica ptica = (Ptica) birdClass.getConstructor (). NewInstance (); Metoda setWalksMethod = birdClass.getDeclaredMethod ("setWalks", boolean.class); Metoda walksMethod = birdClass.getDeclaredMethod ("šetnje"); logičke šetnje = (logičke) walksMethod.invoke (ptica); assertFalse (šetnje); assertFalse (bird.walks ()); setWalksMethod.invoke (ptica, istina); boolean walks2 = (boolean) walksMethod.invoke (bird); assertTrue (šetnje2); assertTrue (bird.walks ()); }

Primijetite kako se prvo pozivamo na šetnje metodu i prebacite tip povrata na odgovarajući tip podataka, a zatim provjerite njegovu vrijednost. Zatim se kasnije pozivamo na setWalks metoda za promjenu te vrijednosti i ponovno testiranje.

9. Zaključak

U ovom smo tutorijalu pokrili Java Reflection API i pogledali kako ga koristiti za inspekciju klasa, sučelja, polja i metoda tijekom izvođenja, bez prethodnog znanja o njihovim internim komponentama tijekom vremena kompajliranja.

Cjeloviti izvorni kod i primjeri za ovaj vodič mogu se naći na GitHubu.


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