java reflection tutorial with examples
Denne videoopplæringen forklarer hva som er refleksjon og hvordan du implementerer den ved hjelp av Reflection API:
Refleksjon i Java er å inspisere og endre oppførselen til et program ved kjøretid.
Ved hjelp av dette refleksjon-API-et kan du inspisere klasser, konstruktører, modifikatorer, felt, metoder og grensesnitt ved kjøretid. For eksempel, du kan få navnet på klassen, eller du kan få detaljer om de private medlemmene i klassen.
Les gjennom hele vår JAVA treningsserie for mer innsikt i Java-konsepter.
Her er en videoopplæring om Java-refleksjon:
Hva du vil lære:
Refleksjon i Java
Vi er klar over at vi i en gitt klasse kan endre dens egenskaper og metoder på kompileringstid, og det er veldig enkelt å gjøre det. Enten egenskapene og metodene er anonyme eller har navn, kan de endres etter eget ønske i løpet av kompileringstiden.
Men vi kan ikke endre disse klassene eller metodene eller feltene i løpet av løpetiden. Det er med andre ord veldig vanskelig å endre oppførselen til forskjellige programmeringskomponenter ved kjøretid, spesielt for ukjente objekter.
Java-programmeringsspråk gir en funksjon som heter 'Speilbilde' som lar oss endre kjøretidsoppførselen til en klasse eller felt eller metode under kjøretiden.
Dermed kan en refleksjon defineres som en “Teknikk for å inspisere og endre kjøretidsoppførselen til et ukjent objekt på kjøretiden. Et objekt kan være en klasse, et felt eller en metode. ”
Reflection er et 'Application Programming Interface' (API) levert av Java.
“Refleksjon” -prosessen er avbildet nedenfor.
I ovenstående representasjon kan vi se at vi har et ukjent objekt. Deretter bruker vi Reflection API på dette objektet. Som et resultat kan vi endre oppførselen til dette objektet i løpetid.
Dermed kan vi bruke Reflection API i programmene våre med det formål å endre objektets oppførsel. Objektene kan være alt som metoder, grensesnitt, klasser osv. Vi inspiserer disse objektene og endrer deretter oppførselen deres ved kjøretid ved hjelp av refleksjon API.
I Java er 'java.lang' og 'java.lang.reflect' de to pakkene som gir klasser for refleksjon. Spesialklassen “java.lang.Class” gir metodene og egenskapene for å trekke ut metadata ved hjelp av hvilke vi kan inspisere og endre klassens atferd.
Vi bruker Reflection API levert av ovennevnte pakker for å endre klassen og dens medlemmer, inkludert felt, metoder, konstruktører, etc. ved kjøretid. Et kjennetegn ved Reflection API er at vi også kan manipulere de private datamedlemmene eller metodene i klassen.
Reflection API brukes hovedsakelig i:
- Refleksjon brukes hovedsakelig i feilsøkingsverktøy, JUnit og rammeverk for å inspisere og endre atferd ved kjøretid.
- IDE (integrert utviklingsmiljø) F.eks. Formørkelse IDE, NetBeans, etc.
- Testverktøy etc.
- Den brukes når applikasjonen din har tredjepartsbiblioteker og når du vil vite om klassene og metodene som er tilgjengelige.
Reflection API i Java
Ved hjelp av Reflection API kan vi implementere refleksjonen på følgende enheter:
- Felt : Feltklassen har informasjon som vi bruker til å erklære en variabel eller et felt som en datatype (int, dobbelt, streng osv.), Tilgangsmodifikator (privat, offentlig, beskyttet osv.), Navn (identifikator) og verdi.
- Metode : Metodeklassen kan hjelpe oss med å trekke ut informasjon som tilgangsmodifikator for metoden, metodetilbaketype, metodenavn, metodeparametertyper og unntakstyper hevet av metoden.
- Bygger : Konstruktorklasse gir informasjon om klassekonstruktør som inkluderer modifikator for konstruktortilgang, konstruktørnavn og parametertyper.
- Redigere : Modifier klasse gir oss informasjon om en spesifikk tilgang modifikator.
Alle klassene ovenfor er en del av pakken java.lang.reflect. Deretter vil vi diskutere hver av disse klassene og bruke programmeringseksempler for å demonstrere refleksjonen over disse klassene.
La oss først begynne med klassen java.lang.Class.
java.lang.Class Class
Klassen inneholder all informasjon og data om klasser og objekter i løpetid. Dette er hovedklassen som brukes til refleksjon.
Klassen java.lang.Class gir:
- Metoder for å hente klassemetadata på kjøretid.
- Metoder for å inspisere og endre oppførselen til en klasse i løpetid.
Lag java.lang.Class Objects
Vi kan lage objekter av java.lang.Class ved å bruke ett av følgende alternativer.
fossemodell i livssyklus for programvareutvikling
# 1) .klassforlengelse
Det første alternativet for å opprette et objekt fra Class er å bruke .class-utvidelsen.
For eksempel,Hvis Test er en klasse, kan vi opprette et Class-objekt som følger:
Class obj_test = Test.class;
Så kan vi bruke obj_test til å utføre refleksjon, da dette objektet vil ha all informasjon om klassen Test.
# 2) forName () -metoden
forName () -metoden tar navnet på klassen som et argument og returnerer Class-objektet.
For eksempel,objektet til testklassen kan opprettes som følger:
class obj_test = Class.forName (“Test”);
# 3) getClas () -metoden
getClass () -metoden bruker objektet til en klasse for å få java.lang.Class-objektet.
For eksempel,vurder følgende kode:
Test obj = new Test (); Class obj_test = obj.getClass ();
I første linje opprettet vi et objekt av testklasse. Deretter kalte vi 'getClass ()' -metoden for å få et objekt obj_test av java.lang.Class ved å bruke dette objektet.
Få Super Class & Access Modifiers
java.lang.class gir en metode “getSuperClass ()” som brukes til å få superklassen til enhver klasse.
På samme måte gir den en metode getModifier () som returnerer tilgangsmodifikatoren til klassen.
Eksemplet nedenfor viser getSuperClass () -metoden.
import java.lang.Class; import java.lang.reflect.*; //define Person interface interface Person { public void display(); } //declare class Student that implements Person class Student implements Person { //define interface method display public void display() { System.out.println('I am a Student'); } } class Main { public static void main(String() args) { try { // create an object of Student class Student s1 = new Student(); // get Class object using getClass() Class obj = s1.getClass(); // get the superclass of Student Class superClass = obj.getSuperclass(); System.out.println('Superclass of Student Class: ' + superClass.getName()); } catch(Exception e) { e.printStackTrace(); } } }
Produksjon
I ovennevnte programmeringseksempel er et grensesnitt Person definert med en ensom metode 'display ()'. Deretter definerer vi en studentklasse som implementerer persongrensesnittet. I hovedmetoden bruker vi getClass () -metoden til å hente Class-objektet og deretter få tilgang til foreldre eller superklasse til Student-objekt ved hjelp av getSuperClass () -metoden.
Få grensesnitt
Hvis klassen implementerer noen grensesnitt, kan vi få disse grensesnittnavnene ved hjelp av getInterfaces () -metoden til java.lang.Class. For dette må vi utføre en refleksjon over Java-klassen.
Programmeringseksemplet nedenfor viser bruken av getInterfaces () -metoden i Java Reflection.
import java.lang.Class; import java.lang.reflect.*; //define Interface Animals and PetAnimals interface Animals { public void display(); } interface PetAnimals { public void makeSound(); } //define a class Dog that implements above interfaces class Dog implements Animals, PetAnimals { //define interface method display public void display() { System.out.println('This is a PetAnimal::Dog'); } //define interface method makeSound public void makeSound() { System.out.println('Dog makes sound::Bark bark'); } } class Main { public static void main(String() args) { try { // create an object of Dog class Dog dog = new Dog(); // get class object Class obj = dog.getClass(); // get the interfaces implemented by Dog Class() objInterface = obj.getInterfaces(); System.out.println('Class Dog implements following interfaces:'); //print all the interfaces implemented by class Dog for(Class citem : objInterface) { System.out.println('Interface Name: ' + citem.getName()); } } catch(Exception e) { e.printStackTrace(); } } }
Produksjon
I programmet ovenfor har vi definert to grensesnitt, dvs. Animals og PetAnimals. Deretter definerer vi en klasse Dog som implementerer begge disse grensesnittene.
I hovedmetoden henter vi gjenstanden til klasse Dog i java.lang.Class for å utføre refleksjon. Deretter bruker vi metoden getInterfaces () for å hente grensesnittene som er implementert av klassen Hund.
Refleksjon: Få feltverdi
Som allerede nevnt gir pakken java.lang.reflect feltklassen som hjelper oss med å reflektere feltet eller dataene i klassen.
Nedenfor er metodene gitt av feltklassen for refleksjon av et felt.
Metode | Beskrivelse |
---|---|
getField ('fieldName') | Returnerer feltet (offentlig) med et spesifisert feltnavn. |
getFields () | Returnerer alle de offentlige feltene (både for klasse og superklasse). |
getDeclaredFields () | Henter alle feltene i klassen. |
getModifier () | Returnerer heltallrepresentasjon av tilgangsmodifikator for feltet. |
sett (classObject, verdi) | Tilordner den angitte verdien til feltet. |
få (classObject) | Henter feltverdi. |
setAccessible (boolean) | Gjør privat felt tilgjengelig ved å passere sant. |
getDeclaredField ('fieldName') | Returnerer feltet med et spesifisert navn. |
Nedenfor er to eksempler på refleksjon som viser refleksjonen på det offentlige og private feltet.
Java-programmet nedenfor viser refleksjonen på et offentlig felt.
import java.lang.Class; import java.lang.reflect.*; class Student { public String StudentName; } class Main { public static void main(String() args) { try{ Student student = new Student(); // get an object of the class Class Class obj = student.getClass(); // provide field name and get the field info Field student_field = obj.getField('StudentName'); System.out.println('Details of StudentName class field:'); // set the value of field student_field.set(student, 'Lacey'); // get the access modifier of StudentName int mod1 = student_field.getModifiers(); String modifier1 = Modifier.toString(mod1); System.out.println('StudentName Modifier::' + modifier1); // get the value of field by converting in String String typeValue = (String)student_field.get(student); System.out.println('StudentName Value::' + typeValue); } catch(Exception e) { e.printStackTrace(); } } }
Produksjon
I dette programmet har vi erklært en klasse 'Student' som har et offentlig felt Studentnavn. Deretter bruker vi API-grensesnittet i feltklassen, og reflekterer i feltet Studentnavn og henter tilgangsmodifikatoren og verdien.
Det neste programmet utfører refleksjon over et privat felt i klassen. Operasjonene er like bortsett fra at det er gjort en ekstra funksjonsanrop for det private feltet. Vi må ringe setAccessible (true) for det private feltet. Deretter utfører vi refleksjon på dette feltet på en lignende måte som det offentlige feltet.
import java.lang.Class; import java.lang.reflect.*; class Student { private String rollNo; } class Main { public static void main(String() args) { try { Student student = new Student(); // get the object for class Student in a Class. Class obj = student.getClass(); // access the private field Field field2 = obj.getDeclaredField('rollNo'); // make the private field accessible field2.setAccessible(true); // set the value of rollNo field2.set(student, '27'); System.out.println('Field Information of rollNo:'); // get the access modifier of rollNo int mod2 = field2.getModifiers(); String modifier2 = Modifier.toString(mod2); System.out.println('rollNo modifier::' + modifier2); // get the value of rollNo converting in String String rollNoValue = (String)field2.get(student); System.out.println('rollNo Value::' + rollNoValue); } catch(Exception e) { e.printStackTrace(); } } }
Produksjon
Refleksjon: Metode
I likhet med feltene i klassen, kan vi også reflektere over klassemetoder og endre deres oppførsel på kjøretid. For dette bruker vi metoden klassen av pakken java.lang.reflect.
Her er funksjonene som tilbys av Metodeklassen for refleksjon av klassemetoden.
Metode | Beskrivelse |
---|---|
getMethods () | Henter alle offentlige metoder som er definert i klassen og superklassen. |
getDeclaredMethod () | Returnerer metoder som er oppgitt i klassen. |
getName () | Returnerer metodenavnene. |
getModifiers () | Returnerer heltallrepresentasjon av metodens tilgangsmodifikator. |
getReturnType () | Returnerer metoden returtype. |
Eksemplet nedenfor viser refleksjon av klassemetoder i Java ved hjelp av API-ene ovenfor.
import java.lang.Class; import java.lang.reflect.*; //declare a class Vehicle with four methods class Vehicle { public void display() { System.out.println('I am a Vehicle!!'); } protected void start() { System.out.println('Vehicle Started!!!'); } protected void stop() { System.out.println('Vehicle Stopped!!!'); } private void serviceVehicle() { System.out.println('Vehicle serviced!!'); } }class Main { public static void main(String() args) { try { Vehicle car = new Vehicle(); // create an object of Class Class obj = car.getClass(); // get all the methods using the getDeclaredMethod() in an array Method() methods = obj.getDeclaredMethods(); // for each method get method info for(Method m : methods) { System.out.println('Method Name: ' + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.print('Modifier: ' + Modifier.toString(modifier) + ' '); // get the return type of method System.out.print('Return Type: ' + m.getReturnType()); System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Produksjon
I det ovennevnte programmet ser vi at metoden getDeclaredMethods returnerer matrisen av metoder deklarert av klassen. Deretter gjentar vi gjennom denne matrisen og viser informasjonen til hver metode.
Refleksjon: Konstruktør
Vi kan bruke klassen 'Constructor' i pakken java.lang.reflect til å inspisere og modifisere konstruktørene til en Java-klasse.
Konstruktorklassen gir følgende metoder for dette formålet.
Metode | Beskrivelse |
---|---|
getConstructors () | Returnerer alle konstruktørene som er oppgitt i klassen og dens superklasse. |
getDeclaredConstructor () | Returnerer alle deklarerte konstruktørene. |
getName () | Henter navnet på konstruktøren. |
getModifiers () | Returnerer heltallrepresentasjonen av tilgangsmodifikatoren til konstruktører. |
getParameterCount () | Returnerer totalt antall parametere for en konstruktør. |
Refleksjonseksemplet nedenfor viser refleksjonen fra konstruktører av en klasse i Java. Som metoderefleksjon, returnerer her også getDeclaredConstructors-metoden en rekke konstruktører for en klasse. Deretter krysser vi gjennom denne konstruktørmatrisen for å vise informasjon om hver konstruktør.
import java.lang.Class; import java.lang.reflect.*; //declare a class Person with three constructors class Person { public Person() { } //constructor with no parameters public Person(String name) { } //constructor with 1 parameter private Person(String name, int age) {} //constructor with 2 parameters } class Main { public static void main(String() args) { try { Person person = new Person(); Class obj = person.getClass(); // get array of constructors in a class using getDeclaredConstructor() Constructor() constructors = obj.getDeclaredConstructors(); System.out.println('Constructors for Person Class:'); for(Constructor c : constructors) { // get names of constructors System.out.println('Constructor Name: ' + c.getName()); // get access modifier of constructors int modifier = c.getModifiers(); System.out.print ('Modifier: ' + Modifier.toString(modifier) + ' '); // get the number of parameters in constructors System.out.println('Parameters: ' + c.getParameterCount()); //if there are parameters, get parameter type of each parameter if(c.getParameterCount() > 0){ Class() paramList=c.getParameterTypes(); System.out.print ('Constructor parameter types :'); for (Class class1 : paramList) { System.out.print(class1.getName() +' '); } } System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Produksjon
Ulemper med refleksjon
Refleksjon er kraftig, men skal ikke brukes uforlignelig. Hvis det er mulig å betjene uten å bruke refleksjon, er det å foretrekke å unngå å bruke den.
Nedenfor er noen ulemper med refleksjon:
- Ytelsesomkostninger: Selv om refleksjon er en kraftig funksjon, har reflekterende operasjoner fortsatt lavere ytelse enn ikke-reflekterende operasjoner. Derfor bør vi unngå å bruke refleksjoner i ytelseskritiske applikasjoner.
- Sikkerhetsbegrensninger: Ettersom refleksjon er en kjøretidsfunksjon, kan det kreve kjøretidstillatelser. Så for applikasjoner som krever at koden skal kjøres i en begrenset sikkerhetsinnstilling, kan refleksjon ikke være til nytte.
- Eksponering av interner: Ved å bruke refleksjon kan vi få tilgang til private felt og metoder i en klasse. Dermed bryter refleksjon abstraksjon som kan gjøre koden uportabel og dysfunksjonell.
ofte stilte spørsmål
Q # 1) Hvorfor brukes refleksjon i Java?
Svar: Ved hjelp av refleksjon kan vi inspisere klasser, grensesnitt, konstruktører, felt og metoder ved kjøretid, selv om de er anonyme på kompileringstidspunktet. Denne inspeksjonen lar oss endre oppførselen til disse enhetene under kjøretid.
Q # 2) Hvor brukes refleksjon?
Svar: Refleksjon brukes i skriftlige rammer som fungerer sammen med brukerdefinerte klasser, der programmereren ikke en gang vet hva klassene eller andre enheter vil være.
Q # 3) Er Java Reflection treg?
Svar: Ja, det er tregere enn ikke-refleksjonskoden.
Q # 4) Er Java Reflection dårlig?
Svar: På en måte, ja. Først og fremst mister vi sikkerhet i kompileringstiden. Uten kompileringstidssikkerhet kan vi få kjøretidsfeil som kan påvirke sluttbrukere. Det vil også være vanskelig å feilsøke feilen.
Q # 5) Hvordan stopper du en refleksjon i Java?
Svar: Vi unngår ganske enkelt å bruke refleksjon ved å skrive operasjoner som ikke reflekterer. Eller kanskje vi kan bruke noen generiske mekanismer som en tilpasset validering med refleksjon.
Mer om Java-refleksjon
java.lang.reflect-pakken har klassene og grensesnittene som skal reflekteres. Og java.lang.klassen kan brukes som inngangspunkt for refleksjonen.
Hvordan få klasseobjektene:
1. Hvis du har forekomst av et objekt,
klasse c = obj.getclass ();
2. Hvis du vet hvilken type klasse,
klasse c = type.getClass ();
3. Hvis du vet kursnavnet,
Klasse c = Class.forName (“com.demo.Mydemoclass”);
Hvordan få klassemedlemmene:
Klassemedlemmer er felt (klassevariabler) og metoder.
- getFields () - Brukes til å få alle feltene bortsett fra de private feltene.
- getDeclaredField () - Brukes for å få de private feltene.
- getDeclaredFields () - Brukes til å få private og offentlige felt.
- getMethods () - Brukt for å få alle metodene unntatt de private metodene.
- getDeclaredMethods () –Brukt for å få offentlige og private metoder.
Demoprogrammer:
ReflectionHelper.java:
Dette er klassen der vi skal inspisere ved hjelp av refleksjon API.
avslappende nettjenester java intervju spørsmål
class ReflectionHelper { private int age; private String name; public String deptName; public int empID; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
ReflectionDemo.java
public class ReflectionDemo { public static void main(String() args) throws NoSuchFieldException, SecurityException { //get the class Class ReflectionHelperclass=ReflectionHelper.class; //get the name of the class String className = ReflectionHelperclass.getName(); System.out.println('className=='+className); System.out.println('getModifiers'+ReflectionHelperclass.getModifier s()); System.out.println('getSuperclass'+ReflectionHelperclass.getSupercla ss()); System.out.println('getPackage'+ReflectionHelperclass.getPackage()); Field() fields =ReflectionHelperclass.getFields(); //getting only the public fields for(Field oneField : fields) { Field field = ReflectionHelperclass.getField(oneField.getName()); String fieldname = field.getName(); System.out.println('only the public fieldnames:::::'+fieldname); } //getting all the fields of the class Field() privatefields =ReflectionHelperclass.getDeclaredFields(); for(Field onefield : privatefields) { Field field = ReflectionHelperclass.getDeclaredField(onefield.getName()); String fieldname = field.getName(); System.out.println('all the fieldnames in the class:::'+fieldname); } Method() methods =ReflectionHelperclass.getDeclaredMethods(); for(Method m: methods) { System.out.println('methods::::'+m.getName()); } }}
Konklusjon
Denne opplæringen forklarte Reflection API i Java i detalj. Vi så hvordan å utføre refleksjon av klasser, grensesnitt, felt, metoder og konstruktører sammen med noen ulemper med refleksjon.
Refleksjon er en relativt avansert funksjon i Java, men bør brukes av programmerere som har et høyborg på språket. Dette er fordi det kan forårsake uventede feil og resultater hvis det ikke brukes med forsiktighet.
Selv om refleksjon er kraftig, bør den brukes forsiktig. Likevel, ved hjelp av refleksjon kan vi utvikle applikasjoner som ikke er klar over klasser og andre enheter frem til kjøretid.
=> Ta en titt på Java Beginners Guide her.
Anbefalt lesing
- Java-skanner klasseveiledning med eksempler
- Java Integer og Java BigInteger Class med eksempler
- JAVA-opplæring for nybegynnere: 100+ praktiske Java-videoveiledninger
- Introduksjon til Java Programming Language - Video Tutorial
- Hva er Java Vector | Java Vector Class Tutorial med eksempler
- Java-grensesnitt og abstrakt klasseopplæring med eksempler
- Java substring () Metode - Veiledning med eksempler
- Java Collections Framework (JCF) Tutorial