Veiledning til Java-refleksjon

1. Oversikt

I denne artikkelen vil vi utforske Java-refleksjon, som lar oss inspisere eller modifisere kjøretidsegenskaper for klasser, grensesnitt, felt og metoder. Dette er spesielt nyttig når vi ikke vet navnene deres på kompileringstidspunktet.

I tillegg kan vi instantiere nye objekter, påkalle metoder og få eller angi feltverdier ved hjelp av refleksjon.

2. Prosjektoppsett

For å bruke Java-refleksjon trenger vi ikke å inkludere noen spesielle krukker, hvilken som helst spesiell konfigurasjon eller Maven-avhengigheter. JDK leveres med en gruppe klasser som er samlet i java.lang.refleksjon pakke spesielt for dette formålet.

Så alt vi trenger å gjøre er å gjøre følgende import til koden vår:

importer java.lang.reflect. *;

og vi er gode å gå.

For å få tilgang til klasse-, metode- og feltinformasjonen til en forekomst vi kaller getClass metode som returnerer kjøretidsklassepresentasjonen av objektet. De returnerte klasse objektet gir metoder for å få tilgang til informasjon om en klasse.

3. Enkelt eksempel

For å få føttene våte, skal vi se på et veldig grunnleggende eksempel som inspiserer feltene til et enkelt Java-objekt ved kjøretid.

La oss lage en enkel Person klasse med bare Navn og alder felt og ingen metoder i det hele tatt. Her er Person-klassen:

offentlig klasse Person {private Strengnavn; privat alder; }

Vi vil nå bruke Java-refleksjon for å oppdage navnene på alle feltene i denne klassen. For å sette pris på kraften til refleksjon, vil vi konstruere en Person objekt og bruk Objekt som referansetype:

@Test offentlig ugyldig givenObject_whenGetsFieldNamesAtRuntime_thenCorrect () {Objekt person = ny person (); Felt [] felt = person.getClass (). GetDeclaredFields (); Liste actualFieldNames = getFieldNames (felt); assertTrue (Arrays.asList ("name", "age") .containsAll (actualFieldNames)); }

Denne testen viser oss at vi er i stand til å få en rekke Field gjenstander fra vår person objekt, selv om referansen til objektet er en overordnet type av det objektet.

I eksemplet ovenfor var vi bare interessert i navnene på disse feltene, men det er mye mer som kan gjøres, og vi vil se flere eksempler på dette i de påfølgende avsnittene.

Legg merke til hvordan vi bruker en hjelpermetode for å trekke ut de faktiske feltnavnene, det er en veldig grunnleggende kode:

privat statisk liste getFieldNames (Field [] felt) {List fieldNames = new ArrayList (); for (Feltfelt: felt) fieldNames.add (field.getName ()); retur feltNavn; }

4. Brukstilfeller for Java-refleksjon

Før vi går videre til de forskjellige funksjonene i Java-refleksjon, vil vi diskutere noen av de vanlige bruksområdene vi kan finne for den. Java-refleksjon er ekstremt kraftig og kan være veldig nyttig på flere måter.

I mange tilfeller har vi for eksempel en navnekonvensjon for databasetabeller. Vi kan velge å legge til konsistens ved å forhåndsfeste tabellnavnene våre med tbl_, slik at det kalles en tabell med studentdata tbl_student_data.

I slike tilfeller kan vi kalle Java-objektet som inneholder studentdata som Student eller StudentData. Deretter bruker vi CRUD-paradigmet, vi har ett inngangspunkt for hver operasjon slik at Skape operasjoner får bare en Gjenstand parameter.

Vi bruker deretter refleksjon for å hente objektnavnet og feltnavnene. På dette tidspunktet kan vi kartlegge disse dataene til en DB-tabell og tildele objektfeltverdiene til de aktuelle DB-feltnavnene.

5. Inspisere Java-klasser

I denne delen vil vi utforske den mest grunnleggende komponenten i Java refleksjon API. Java-klasseobjekter, som vi nevnte tidligere, gir oss tilgang til de interne detaljene til ethvert objekt.

Vi skal undersøke interne detaljer som objektets klassenavn, modifikatorer, felt, metoder, implementerte grensesnitt, etc.

5.1. Gjør seg klar

For å få et godt grep om refleksjon API, som brukt på Java-klasser og har eksempler med variasjon, vil vi lage et abstrakt Dyr klasse som implementerer Spiser grensesnitt. Dette grensesnittet definerer spiseadferd til betong Dyr objekt vi lager.

Så for det første, her er Spiser grensesnitt:

offentlig grensesnitt Spise {String eats (); }

og deretter betongen Dyr gjennomføring av Spiser grensesnitt:

offentlig abstrakt klasse Dyreutstyr Spise {offentlig statisk streng CATEGORY = "domestic"; privat strengnavn; beskyttet abstrakt String getSound (); // konstruktør, standard getters og setter utelatt}

La oss også opprette et annet grensesnitt som heter Bevegelse som beskriver hvordan et dyr beveger seg:

offentlig grensesnitt Locomotion {String getLocomotion (); }

Vi skal nå lage en konkret klasse som heter Geit som strekker seg Dyr og redskaper Bevegelse. Siden superklassen implementerer Spiser, Geit må også implementere grensesnittets metoder:

offentlig klasse Geit utvider Dyreutstyr Locomotion {@Override-beskyttet String getSound () {return "bleat"; } @ Override public String getLocomotion () {returner "turer"; } @ Override public String eats () {return "grass"; } // konstruktør utelatt}

Fra dette punktet og utover vil vi bruke Java-refleksjon for å inspisere aspekter av Java-objekter som vises i klassene og grensesnittene ovenfor.

5.2. Klassenavn

La oss starte med å hente navnet på et objekt fra Klasse:

@Test offentlig ugyldighet gittObject_whenGetsClassName_thenCorrect () {Object geit = ny geit ("geit"); Class clazz = goat.getClass (); assertEquals ("Geit", clazz.getSimpleName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getCanonicalName ()); }

Merk at getSimpleName Metode av Klasse returnerer det grunnleggende navnet på objektet slik det ville vises i erklæringen. Deretter returnerer de to andre metodene det fullt kvalifiserte klassenavnet inkludert pakkedeklarasjonen.

La oss også se hvordan vi kan lage et objekt av Geit klasse hvis vi bare vet det fullt kvalifiserte klassenavnet:

@Test offentlig ugyldig givenClassName_whenCreatesObject_thenCorrect () {Class clazz = Class.forName ("com.baeldung.reflection.Goat"); assertEquals ("Geit", clazz.getSimpleName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getName ()); assertEquals ("com.baeldung.reflection.Goat", clazz.getCanonicalName ()); }

Legg merke til at navnet vi overfører til det statiske forName metoden skal inneholde pakkeinformasjonen. Ellers får vi en ClassNotFoundException.

5.3. Klassemodifikatorer

Vi kan bestemme modifikatorene som brukes i en klasse ved å ringe getModifiers metode som returnerer en Heltall. Hver modifikator er en flaggbit som enten er satt eller fjernet.

De java.lang.reflect.Modifier klasse tilbyr statiske metoder som analyserer de returnerte Heltall for tilstedeværelse eller fravær av en spesifikk modifikator.

La oss bekrefte modifikatorene til noen av klassene vi definerte ovenfor:

@Test offentlig ugyldig givenClass_whenRecognisesModifiers_thenCorrect () {Class goatClass = Class.forName ("com.baeldung.reflection.Goat"); Class 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)); }

Vi er i stand til å inspisere modifikatorer av alle klasser som ligger i en bibliotekbur som vi importerer til prosjektet vårt.

I de fleste tilfeller kan det hende vi trenger å bruke forName tilnærming snarere enn fullstendig instantiering siden det ville være en kostbar prosess i tilfelle minne tunge klasser.

5.4. Pakkeinformasjon

Ved å bruke Java-refleksjon kan vi også få informasjon om pakken til hvilken som helst klasse eller gjenstand. Disse dataene er samlet inne i Pakke klasse som returneres ved en samtale til getPackage metode på klasseobjektet.

La oss kjøre en test for å hente pakkenavnet:

@Test offentlig ugyldighet givenClass_whenGetsPackageInfo_thenCorrect () {Geitgeit = ny geit ("geit"); Class goatClass = goat.getClass (); Pakke pkg = goatClass.getPackage (); assertEquals ("com.baeldung.reflection", pkg.getName ()); }

5.5. Super klasse

Vi er også i stand til å få superklassen til hvilken som helst Java-klasse ved hjelp av Java-refleksjon.

I mange tilfeller, spesielt når vi bruker biblioteklasser eller Java's innebygde klasser, vet vi kanskje ikke på forhånd superklassen til et objekt vi bruker, dette underavsnittet viser hvordan du får tak i denne informasjonen.

Så la oss gå videre og bestemme superklassen til Geit. I tillegg viser vi det også java.lang.Streng klasse er en underklasse av java.lang.Objekt klasse:

@Test offentlig ugyldighet givenClass_whenGetsSuperClass_thenCorrect () {Geitgeit = ny geit ("geit"); String str = "any string"; Class goatClass = goat.getClass (); Class goatSuperClass = goatClass.getSuperclass (); assertEquals ("Animal", goatSuperClass.getSimpleName ()); assertEquals ("Object", str.getClass (). getSuperclass (). getSimpleName ()); }

5.6. Implementerte grensesnitt

Ved hjelp av Java-refleksjon er vi også i stand til det få listen over grensesnitt implementert av en gitt klasse.

La oss hente klassetyper av grensesnittene implementert av Geit klasse og Dyr abstrakt klasse:

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

Legg merke til påstandene om at hver klasse kun implementerer et enkelt grensesnitt. Ved å inspisere navnene på disse grensesnittene, finner vi det Geit redskaper Bevegelse og Dyr redskaper Spiser, akkurat som det vises i koden vår.

Du har kanskje observert det Geit er en underklasse av den abstrakte klassen Dyr og implementerer grensesnittmetoden spiser (), deretter, Geit implementerer også Spiser grensesnitt.

Det er derfor verdt å merke seg at bare de grensesnittene som en klasse eksplisitt erklærer som implementert med redskaper nøkkelord vises i den returnerte matrisen.

Så selv om en klasse implementerer grensesnittmetoder fordi superklassen implementerer det grensesnittet, men underklassen erklærer ikke direkte grensesnittet med redskaper nøkkelordet, da vises ikke det grensesnittet i grensesnittet.

5.7. Konstruktører, metoder og felt

Med Java-refleksjon er vi i stand til å inspisere konstruktørene av hvilket som helst objekts klasse, samt metoder og felt.

Vi vil senere kunne se dypere inspeksjoner på hver av disse komponentene i en klasse, men foreløpig er det tilstrekkelig å bare få navnene deres og sammenligne dem med det vi forventer.

La oss se hvordan vi kan få konstruktøren til Geit klasse:

@Test offentlig ugyldig givenClass_whenGetsConstructor_thenCorrect () {Class goatClass = Class.forName ("com.baeldung.reflection.Goat"); Constructor [] constructors = goatClass.getConstructors (); assertEquals (1, constructors.length); assertEquals ("com.baeldung.reflection.Goat", konstruktører [0] .getName ()); }

Vi kan også inspisere feltene i Dyr klasse slik:

@Test offentlig ugyldig givenClass_whenGetsFields_thenCorrect () {Class animalClass = Class.forName ("com.baeldung.reflection.Animal"); Felt [] felt = animalClass.getDeclaredFields (); Liste actualFields = getFieldNames (felt); assertEquals (2, actualFields.size ()); assertTrue (actualFields.containsAll (Arrays.asList ("navn", "KATEGORI"))); }

Akkurat som vi kan inspisere metodene til Dyr klasse:

@Test offentlig ugyldig givenClass_whenGetsMethods_thenCorrect () {Class animalClass = Class.forName ("com.baeldung.reflection.Animal"); Metode [] metoder = animalClass.getDeclaredMethods (); Liste actualMethods = getMethodNames (metoder); assertEquals (4, actualMethods.size ()); assertTrue (actualMethods.containsAll (Arrays.asList ("getName", "setName", "getSound"))); }

Akkurat som getFieldNames, har vi lagt til en hjelpermetode for å hente metodenavn fra en rekke Metode gjenstander:

privat statisk liste getMethodNames (Method [] metoder) {List methodNames = new ArrayList (); for (Metodemetode: metoder) methodNames.add (method.getName ()); retur metode Navn; }

6. Inspisere konstruksjoner

Med Java-refleksjon kan vi inspisere konstruktører av hvilken som helst klasse og til og med lage klasseobjekter ved kjøretid. Dette er muliggjort av java.lang.reflect.Constructor klasse.

Tidligere så vi bare på hvordan vi skulle få en rekke Konstruktør gjenstander, hvorfra vi klarte å få navnene på konstruktørene.

I denne delen vil vi fokusere på hvordan man kan hente frem spesifikke konstruktører. I Java, som vi vet, deler ikke to konstruktører av en klasse nøyaktig samme metodesignatur. Så vi vil bruke denne unikheten til å få en konstruktør fra mange.

For å sette pris på funksjonene i denne klassen, vil vi lage en Fugl underklasse av Dyr med tre konstruktører. Vi vil ikke implementere Bevegelse slik at vi kan spesifisere atferden ved hjelp av et konstruktørargument, for å legge til enda mer variasjon:

offentlig klasse Bird utvider Animal {private boolske turer; offentlig Bird () {super ("bird"); } offentlig fugl (strengnavn, boolsk vandring) {super (navn); setWalks (turer); } offentlig fugl (strengnavn) {super (navn); } offentlige boolske turer () {returturer; } // standard settere og overstyrte metoder}

La oss bekrefte ved å bruke refleksjon at denne klassen har tre konstruktører:

@Test offentlig ugyldig givenClass_whenGetsAllConstructors_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Constructor [] constructors = birdClass.getConstructors (); assertEquals (3, constructors.length); }

Deretter vil vi hente hver konstruktør for Fugl klasse ved å sende konstruktørens parameterklassetyper i deklarert rekkefølge:

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

Det er ikke behov for påstand siden når en konstruktør med gitte parametertyper i den angitte rekkefølgen ikke eksisterer, vil vi få en NoSuchMethodException og testen mislykkes automatisk.

I den siste testen vil vi se hvordan du kan instantiere objekter i løpetid mens du leverer parametrene:

@Test offentlig ugyldig givenClass_whenInstantiatesObjectsAtRuntime_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Constructor cons1 = birdClass.getConstructor (); Constructor cons2 = birdClass.getConstructor (String.class); Constructor cons3 = birdClass.getConstructor (String.class, boolean.class); Bird bird1 = (Bird) cons1.newInstance (); Bird bird2 = (Bird) cons2.newInstance ("Weaver bird"); Bird bird3 = (Bird) cons3.newInstance ("due", sant); assertEquals ("bird", bird1.getName ()); assertEquals ("Weaver bird", bird2.getName ()); assertEquals ("due", bird3.getName ()); assertFalse (bird1.walks ()); assertTrue (bird3.walks ()); }

Vi instantierer klasseobjekter ved å ringe newInstance Metode av Konstruktør klasse og passere de nødvendige parametrene i deklarert rekkefølge. Vi kaster deretter resultatet til ønsket type.

Det er også mulig å ringe til standardkonstruktøren ved hjelp av Class.newInstance () metode. Denne metoden er imidlertid avviklet siden Java 9, og vi bør ikke bruke den i moderne Java-prosjekter.

Til fugl1, bruker vi standardkonstruktøren som fra vår Fugl kode, setter navnet automatisk til fugl, og vi bekrefter det med en test.

Vi instanserer deretter fugl2 med bare et navn og en test også, husk at når vi ikke angir bevegelsesatferd, da det er standard som falsk, som det fremgår av de to siste påstandene.

7. Inspisere felt

Tidligere inspiserte vi bare navnene på feltene, i denne delen, vi skal vise hvordanfå og angi verdiene sine ved kjøretid.

Det er to hovedmetoder som brukes til å inspisere felt i en klasse ved kjøretid: getFields () og getField (fieldName).

De getFields () metoden returnerer alle tilgjengelige offentlige felt i den aktuelle klassen. Det vil returnere alle de offentlige feltene i både klassen og alle superklasser.

For eksempel når vi kaller denne metoden på Fugl klasse, får vi bare KATEGORI felt av sin superklasse, Dyr, siden Fugl selv erklærer ikke noen offentlige felt:

@Test offentlig ugyldig givenClass_whenGetsPublicFields_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Felt [] felt = birdClass.getFields (); assertEquals (1, felt.lengde); assertEquals ("CATEGORY", felt [0] .getName ()); }

Denne metoden har også en variant som kalles getField som bare returnerer en Felt objekt ved å ta navnet på feltet:

@Test offentlig ugyldig givenClass_whenGetsPublicFieldByName_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Feltfelt = birdClass.getField ("KATEGORI"); assertEquals ("CATEGORY", field.getName ()); }

Vi har ikke tilgang til private felt deklarert i superklasser og ikke deklarert i barneklassen. Dette er grunnen til at vi ikke har tilgang til Navn felt.

Imidlertid kan vi inspisere private felt erklært i klassen vi har å gjøre med ved å ringe getDeclaredFields metode:

@Test offentlig ugyldig givenClass_whenGetsDeclaredFields_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Felt [] felt = birdClass.getDeclaredFields (); assertEquals (1, felt.lengde); assertEquals ("går", felt [0] .getName ()); }

Vi kan også bruke den andre varianten i tilfelle vi vet navnet på feltet:

@Test offentlig ugyldig givenClass_whenGetsFieldsByName_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Feltfelt = birdClass.getDeclaredField ("går"); assertEquals ("går", field.getName ()); }

Hvis vi får navnet på feltet feil eller skriver inn et eksisterende felt, får vi et NoSuchFieldException.

Vi får felttypen som følger:

@Test offentlig ugyldig givenClassField_whenGetsType_thenCorrect () {Field field = Class.forName ("com.baeldung.reflection.Bird") .getDeclaredField ("walk"); Class fieldClass = field.getType (); assertEquals ("boolean", fieldClass.getSimpleName ()); }

Deretter vil vi se på hvordan du får tilgang til feltverdier og endrer dem. For å kunne få verdien av et felt, enn si å sette det, må vi først stille det tilgjengelig ved å ringe setTilgjengelig metoden på Felt motsette og passere boolsk ekte til det:

@Test offentlig ugyldig givenClassField_whenSetsAndGetsValue_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Bird bird = (Bird) birdClass.getConstructor (). NewInstance (); Feltfelt = birdClass.getDeclaredField ("går"); field.setAccessible (true); assertFalse (field.getBoolean (fugl)); assertFalse (bird.walks ()); field.set (fugl, sant); assertTrue (field.getBoolean (fugl)); assertTrue (bird.walks ()); }

I testen ovenfor fastslår vi at virkelig verdien av går feltet er usant før du setter det til sant.

Legg merke til hvordan vi bruker Felt objekt for å sette og få verdier ved å sende den forekomsten av klassen vi har å gjøre med og muligens den nye verdien vi vil at feltet skal ha i det objektet.

En viktig ting å merke seg Felt objekter er at når det blir erklært som offentlig statisk, så trenger vi ikke en forekomst av klassen som inneholder dem, vi kan bare passere null på plass og fremdeles oppnå standardverdien for feltet, slik:

@Test offentlig ugyldig givenClassField_whenGetsAndSetsWithNull_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Feltfelt = birdClass.getField ("KATEGORI"); field.setAccessible (true); assertEquals ("domestic", field.get (null)); }

8. Inspeksjonsmetoder

I et tidligere eksempel brukte vi bare refleksjon for å inspisere metodenavn. Imidlertid er Java-refleksjon kraftigere enn det.

Med Java-refleksjon kan vi påkalle metoder kl kjøretid og gi dem de nødvendige parametrene, akkurat som vi gjorde for konstruktører. På samme måte kan vi også påkalle overbelastede metoder ved å spesifisere parametertyper for hver.

Akkurat som felt er det to hovedmetoder som vi bruker for å hente klassemetoder. De getMethods metoden returnerer en rekke med alle offentlige metoder i klassen og superklasser.

Dette betyr at med denne metoden kan vi få offentlige metoder for java.lang.Objekt klasse som toString, hashCode, og varsleAlle:

@Test offentlig ugyldig givenClass_whenGetsAllPublicMethods_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Metode [] metoder = birdClass.getMethods (); Liste methodNames = getMethodNames (metoder); assertTrue (methodNames.containsAll (Arrays .asList ("er lik", "notifyAll", "hashCode", "går", "spiser", "toString"))); }

For å få bare offentlige metoder for den klassen vi er interessert i, må vi bruke getDeclaredMethods metode:

@Test offentlig ugyldig givenClass_whenGetsOnlyDeclaredMethods_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Liste actualMethodNames = getMethodNames (birdClass.getDeclaredMethods ()); Liste expectMethodNames = Arrays .asList ("setWalks", "promenader", "getSound", "spiser"); assertEquals (expectMethodNames.size (), actualMethodNames.size ()); assertTrue (expectMethodNames.containsAll (actualMethodNames)); assertTrue (actualMethodNames.containsAll (expectMethodNames)); }

Hver av disse metodene har enestående variasjon som returnerer en singel Metode objekt hvis navn vi kjenner:

@Test offentlig ugyldig givenMethodName_whenGetsMethod_thenCorrect () kaster Unntak {Bird bird = new Bird (); Metode walkMethod = bird.getClass (). GetDeclaredMethod ("går"); Method setWalksMethod = bird.getClass (). GetDeclaredMethod ("setWalks", boolean.class); assertTrue (walkMethod.canAccess (bird)); assertTrue (setWalksMethod.canAccess (bird)); }

Legg merke til hvordan vi henter individuelle metoder og spesifiserer hvilke parametertyper de tar. De som ikke tar parametertyper, blir hentet med et tomt variabelargument, slik at vi bare har ett enkelt argument, metodens navn.

Deretter vil vi vise hvordan vi kan påkalle en metode ved kjøretid. Vi vet som standard at går attributt til Fugl klasse er falsk, vi vil kalle det setWalks metode og sett den til ekte:

@Test public void givenMethod_whenInvokes_thenCorrect () {Class birdClass = Class.forName ("com.baeldung.reflection.Bird"); Bird bird = (Bird) birdClass.getConstructor (). NewInstance (); Method setWalksMethod = birdClass.getDeclaredMethod ("setWalks", boolean.class); Metode walkMethod = birdClass.getDeclaredMethod ("går"); boolske turer = (boolske) turerMetode.påkalle (fugl); assertFalske (går); assertFalse (bird.walks ()); setWalksMethod.invoke (fugl, sant); boolsk vandring2 = (boolsk) gårMetode.invoke (fugl); assertTrue (promenader2); assertTrue (bird.walks ()); }

Legg merke til hvordan vi først påkaller går metode og kast returtypen til riktig datatype, og kontroller deretter verdien. Vi påkaller deretter senere setWalks metode for å endre den verdien og teste igjen.

9. Konklusjon

I denne opplæringen har vi dekket Java Reflection API og sett på hvordan vi kan bruke den til å inspisere klasser, grensesnitt, felt og metoder under kjøretid uten forutgående kunnskap om deres interne etter kompileringstid.

Den fullstendige kildekoden og eksemplene for denne opplæringen finner du på GitHub.


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