java reflection tutorial with examples
Denne videovejledning forklarer, hvad der er refleksion, og hvordan man implementerer det ved hjælp af Reflection API:
Refleksion i Java er at inspicere og ændre et programs opførsel ved kørsel.
Ved hjælp af denne refleksions-API kan du inspicere klasser, konstruktører, modifikatorer, felter, metoder og grænseflader under kørsel. For eksempel, du kan få navnet på klassen, eller du kan få detaljer om de private medlemmer af klassen.
Læs hele vores JAVA træningsserie for mere indsigt i Java-koncepter.
Her er en videovejledning om Java-refleksion:
Hvad du lærer:
Refleksion i Java
Vi er opmærksomme på, at vi i en given klasse kan ændre dens egenskaber og metoder på kompileringstidspunktet, og det er meget let at gøre det. Uanset om egenskaberne og metoderne er anonyme eller har navne, kan de ændres efter vores vilje i kompileringstiden.
Men vi kan ikke ændre disse klasser eller metoder eller felter under kørsel på farten. Med andre ord er det meget vanskeligt at ændre adfærd for forskellige programmeringskomponenter ved kørsel, især for ukendte objekter.
Java-programmeringssprog giver en funktion kaldet 'Afspejling' der giver os mulighed for at ændre kørselsadfærden for en klasse, felt eller metode under kørsel.
En refleksion kan således defineres som en “Teknik til inspektion og ændring af et ukendt objekts kørselsadfærd på kørselstid. Et objekt kan være en klasse, et felt eller en metode. ”
Reflection er et “Application Programming Interface” (API) leveret af Java.
Processen med 'Refleksion' er vist nedenfor.
I ovenstående repræsentation kan vi se, at vi har et ukendt objekt. Derefter bruger vi Reflection API på dette objekt. Som et resultat kan vi ændre dette objekts opførsel under kørsel.
Således kan vi bruge Reflection API i vores programmer med det formål at ændre objektets adfærd. Objekterne kan være alt som metoder, grænseflader, klasser osv. Vi inspicerer disse objekter og ændrer derefter deres adfærd ved kørsel ved hjælp af refleksions-API.
I Java er 'java.lang' og 'java.lang.reflect' de to pakker, der giver klasser til refleksion. Den specielle klasse “java.lang.Class” giver metoderne og egenskaberne til at udtrække metadata ved hjælp af hvilke vi kan inspicere og ændre klassens adfærd.
Vi bruger Reflection API leveret af ovenstående pakker til at ændre klassen og dens medlemmer inklusive felter, metoder, konstruktører osv. Under kørsel. Et kendetegn ved Reflection API er, at vi også kan manipulere klassens private datamedlemmer eller metoder.
Reflection API bruges hovedsageligt i:
- Refleksion bruges hovedsageligt i fejlfindingsværktøjer, JUnit og rammer til at inspicere og ændre adfærd under kørsel.
- IDE (integreret udviklingsmiljø) For eksempel. Formørkelse IDE, NetBeans osv.
- Testværktøjer osv.
- Det bruges, når din applikation har tredjepartsbiblioteker, og når du vil vide om de tilgængelige klasser og metoder.
Reflection API i Java
Ved hjælp af Reflection API kan vi implementere refleksionen på følgende enheder:
- Mark : Feltklassen har oplysninger, som vi bruger til at erklære en variabel eller et felt som en datatype (int, dobbelt, streng osv.), Adgangsmodifikator (privat, offentlig, beskyttet osv.), Navn (identifikator) og værdi.
- Metode : Metodeklassen kan hjælpe os med at udtrække information som adgangsmodifikator af metoden, metodetilbagekørselstype, metodens navn, metodeparametertyper og undtagelsestyper, der er hævet af metoden.
- Bygger : Konstruktorklasse giver information om klassekonstruktør, der inkluderer konstruktionsadgangsmodifikator, konstruktørnavn og parametertyper.
- Redigere : Modifier klasse giver os oplysninger om en bestemt adgangsmodifikator.
Alle ovennævnte klasser er en del af pakken java.lang.reflect. Dernæst vil vi diskutere hver af disse klasser og bruge programmeringseksempler til at demonstrere refleksionen over disse klasser.
Lad os starte med klassen java.lang.Class.
java.lang.klasse klasse
Klassen indeholder al information og data om klasser og objekter under kørsel. Dette er hovedklassen, der bruges til refleksion.
Klassen java.lang.Class indeholder:
- Metoder til at hente klassemetadata på kørselstid.
- Metoder til at inspicere og ændre en klasses adfærd i løbetid.
Opret java.lang.Class Objects
Vi kan oprette objekter af java.lang.Class ved hjælp af en af følgende muligheder.
ur i ur ud software gratis
# 1) .klasseudvidelse
Den første mulighed for at oprette et objekt fra Class er ved hjælp af .class-udvidelsen.
For eksempel,hvis Test er en klasse, kan vi oprette et klasseobjekt som følger:
Class obj_test = Test.class;
Derefter kan vi bruge obj_test til at udføre refleksion, da dette objekt vil have alle oplysninger om klassetesten.
# 2) forName () metode
metoden forName () tager navnet på klassen som et argument og returnerer klasseobjektet.
For eksempel,genstanden for testklassen kan oprettes som følger:
class obj_test = Class.forName (“Test”);
# 3) getClas () metode
getClass () -metoden bruger objekt fra en klasse til at hente objektet java.lang.Class.
For eksempel,overvej følgende stykke kode:
Test obj = new Test (); Class obj_test = obj.getClass ();
I den første linje oprettede vi et objekt af testklassen. Derefter kaldte vi 'getClass ()' -metoden ved hjælp af dette objekt for at få et objekt obj_test af java.lang.Class.
Få Super Class & Access Modifiers
java.lang.class giver en metode 'getSuperClass ()', der bruges til at få superklassen i enhver klasse.
På samme måde giver det en metode getModifier (), der returnerer adgangsmodifikatoren for klassen.
Eksemplet nedenfor viser metoden getSuperClass ().
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(); } } }
Produktion
I ovenstående programmeringseksempel er en grænseflade Person defineret med en ensom metode 'display ()'. Derefter definerer vi en elevklasse, der implementerer persongrænsefladen. I hovedmetoden bruger vi getClass () -metoden til at hente Class-objektet og derefter få adgang til overordnet eller superklassen til Student-objektet ved hjælp af getSuperClass () -metoden.
Få grænseflader
Hvis klassen implementerer nogle grænseflader, kan vi få disse grænsefladesnavne ved hjælp af getInterfaces () -metoden i java.lang.Class. Til dette er vi nødt til at udføre en refleksion over Java-klassen.
Nedenstående programmeringseksempel viser brugen af 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(); } } }
Produktion
I ovenstående program har vi defineret to grænseflader, dvs. dyr og petanimaler. Derefter definerer vi en klasse Dog, der implementerer begge disse grænseflader.
I hovedmetoden henter vi objektet fra klasse Dog i java.lang.Class for at udføre refleksion. Derefter bruger vi getInterfaces () -metoden til at hente de grænseflader, der implementeres af klassen Hund.
Refleksion: Få feltværdi
Som allerede nævnt leverer pakken java.lang.reflect feltklassen, der hjælper os med at reflektere feltet eller datamedlemmerne i klassen.
Nedenfor er de metoder, der leveres af feltklassen til refleksion af et felt.
Metode | Beskrivelse |
---|---|
getField ('fieldName') | Returnerer feltet (offentligt) med et angivet feltnavn. |
getFields () | Returnerer alle de offentlige felter (både for klasse og superklasse). |
getDeclaredFields () | Henter alle felterne i klassen. |
getModifier () | Returnerer heltalsrepræsentation af adgangsmodifikator for feltet. |
sæt (classObject, værdi) | Tildeler den angivne værdi til feltet. |
få (classObject) | Henter feltværdi. |
setAccessible (boolean) | Gør privat felt tilgængeligt ved at videregive sandt. |
getDeclaredField ('fieldName') | Returnerer feltet med et angivet navn. |
Nedenfor er to refleksionseksempler, der demonstrerer refleksionen på det offentlige og private felt.
Java-programmet nedenfor viser refleksionen på et offentligt 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(); } } }
Produktion
I dette program har vi erklæret en klasse 'Student' med et offentligt felt StudentName. Derefter bruger vi API-grænsefladen i feltklassen, og vi reflekterer over feltet StudentName og henter dets adgangsmodifikator og værdi.
Det næste program reflekterer over et privat felt i klassen. Funktionerne er ens, bortset fra at der er foretaget et ekstra funktionsopkald til det private felt. Vi er nødt til at kalde setAccessible (true) til det private felt. Derefter udfører vi refleksion på dette felt på en lignende måde som det offentlige felt.
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(); } } }
Produktion
Refleksion: Metode
Svarende til felterne i klassen kan vi også reflektere over klassemetoder og ændre deres adfærd i løbetid. Til dette bruger vi metoden klasse java.lang.reflect pakke.
Nedenfor er de funktioner, der leveres af metodeklassen til refleksion af klassemetoden.
Metode | Beskrivelse |
---|---|
getMethods () | Henter alle offentlige metoder, der er defineret i klassen og dens superklasse. |
getDeclaredMethod () | Returnerer metoder, der er angivet i klassen. |
getName () | Returnerer metodens navne. |
getModifiers () | Returnerer heltalsrepræsentation af metodens adgangsmodifikator. |
getReturnType () | Returnerer metoden returneringstype. |
Nedenstående eksempel viser afspejling af klassemetoder i Java ved hjælp af ovenstående API'er.
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(); } } }
Produktion
I ovenstående program ser vi, at metoden getDeclaredMethods returnerer den række af metoder, der er erklæret af klassen. Derefter gentager vi dette array og viser oplysningerne om hver metode.
Refleksion: Konstruktør
Vi kan bruge klassen 'Constructor' i pakken java.lang.reflect til at inspicere og ændre konstruktørerne af en Java-klasse.
Konstruktorklassen giver følgende metoder til dette formål.
Metode | Beskrivelse |
---|---|
getConstructors () | Returnerer alle konstruktører, der er erklæret i klassen, og dens superklasse. |
getDeclaredConstructor () | Returnerer alle de erklærede konstruktører. |
getName () | Henter navnet på konstruktøren. |
getModifiers () | Returnerer heltalets repræsentation af adgangsmodifikator for konstruktører. |
getParameterCount () | Returnerer det samlede antal parametre for en konstruktør. |
Refleksionseksemplet nedenfor viser refleksionen af konstruktører fra en klasse i Java. Ligesom metodereflektion returnerer her også getDeclaredConstructors-metoden en række konstruktører til en klasse. Derefter krydser vi gennem dette konstruktørarray for at få vist oplysninger 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(); } } }
Produktion
Ulemper ved refleksion
Refleksion er stærk, men bør ikke bruges uden forskel. Hvis det er muligt at betjene uden brug af refleksion, er det at foretrække at undgå at bruge det.
Nedenfor er der få ulemper ved refleksion:
- Ydelsesomkostninger: Selvom refleksion er en stærk funktion, har reflekterende operationer stadig langsommere ydeevne end ikke-reflekterende operationer. Derfor bør vi undgå at bruge refleksioner i ydeevnekritiske applikationer.
- Sikkerhedsbegrænsninger: Da refleksion er en runtime-funktion, kan det kræve tilladelser til kørselstid. Så for applikationer, der kræver, at koden skal udføres i en begrænset sikkerhedsindstilling, kan refleksion måske ikke være til nogen nytte.
- Eksponering af interner: Ved at bruge refleksion kan vi få adgang til private felter og metoder i en klasse. Således bryder refleksion abstraktion, der kan gøre koden uportabel og dysfunktionel.
Ofte stillede spørgsmål
Q # 1) Hvorfor bruges refleksion i Java?
Svar: Ved hjælp af refleksion kan vi inspicere klasser, grænseflader, konstruktører, felter og metoder under kørsel, selvom de er anonyme på kompileringstidspunktet. Denne inspektion giver os mulighed for at ændre disse enheds adfærd under kørsel.
Q # 2) Hvor bruges refleksion?
Svar: Refleksion bruges i skriftlige rammer, der interagerer med brugerdefinerede klasser, hvor programmereren ikke engang ved, hvad klasser eller andre enheder vil være.
Q # 3) Er Java-refleksion langsom?
Svar: Ja, det er langsommere end ikke-refleksionskoden.
Q # 4) Er Java Reflection dårlig?
Svar: På en måde, ja. Først og fremmest mister vi sikkerhed i kompileringstid. Uden sikkerhed i kompileringstid får vi muligvis fejl i løbetid, der kan påvirke slutbrugere. Det vil også være vanskeligt at fejle fejlen.
Q # 5) Hvordan stopper du en refleksion i Java?
Svar: Vi undgår simpelthen at bruge refleksion ved at skrive ikke-refleksionsoperationer. Eller måske kan vi bruge nogle generiske mekanismer som en brugerdefineret validering med refleksion.
Mere om Java-refleksion
java.lang.reflect-pakken har klasser og grænseflader, der skal reflekteres. Og java.lang.class kan bruges som et indgangspunkt for refleksionen.
Sådan får du klasseobjekterne:
1. Hvis du har forekomst af et objekt,
klasse c = obj.getclass ();
2. Hvis du kender klassen,
klasse c = type.getClass ();
3. Hvis du kender klassens navn,
Klasse c = Class.forName (“com.demo.Mydemoclass”);
Sådan får du klassemedlemmerne:
Klassemedlemmer er felter (klassevariabler) og metoder.
- getFields () - Bruges til at få alle felter undtagen de private felter.
- getDeclaredField () - Bruges til at hente de private felter.
- getDeclaredFields () - Bruges til at hente de private og offentlige felter.
- getMethods () - Bruges til at hente alle metoderne undtagen de private metoder.
- getDeclaredMethods () –Bruges for at få de offentlige og private metoder.
Demoprogrammer:
ReflectionHelper.java:
Dette er den klasse, hvor vi skal inspicere ved hjælp af refleksions-API.
hvordan man retter udefineret reference i c ++
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()); } }}
Konklusion
Denne tutorial forklarede Reflection API i Java i detaljer. Vi så, hvordan man udfører refleksion af klasser, grænseflader, felter, metoder og konstruktører sammen med et par ulemper ved refleksion.
Refleksion er en relativt avanceret funktion i Java, men skal bruges af programmører, der har et højborg på sproget. Dette skyldes, at det kan forårsage uventede fejl og resultater, hvis det ikke bruges med forsigtighed.
Selvom refleksion er kraftig, skal den bruges omhyggeligt. Ikke desto mindre kan vi ved hjælp af refleksion udvikle applikationer, der ikke er opmærksomme på klasser og andre enheder indtil runtime.
=> Se på Java Beginners Guide her.
Anbefalet læsning
- Java Scanner-klassevejledning med eksempler
- Java-heltal og Java BigInteger-klasse med eksempler
- JAVA-vejledning til begyndere: 100+ praktiske Java-videovejledninger
- Introduktion til Java-programmeringssprog - Videovejledning
- Hvad er Java Vector | Java Vector Class Tutorial med eksempler
- Java-interface og abstrakt klasseundervisning med eksempler
- Java substring () Metode - Vejledning med eksempler
- Java Collections Framework (JCF) vejledning