java reflection tutorial with examples
Denna videohandledning förklarar vad som är Reflektion och hur man implementerar det med Reflection API:
Reflektion i Java är att inspektera och ändra beteendet hos ett program vid körning.
Med hjälp av detta reflektions-API kan du inspektera klasser, konstruktörer, modifierare, fält, metoder och gränssnitt vid körning. Till exempel, du kan få namnet på klassen eller så kan du få information om de privata medlemmarna i klassen.
Läs igenom hela vår JAVA-träningsserie för mer insikt om Java-koncept.
Här är en videohandledning om Java-reflektion:
Vad du kommer att lära dig:
Reflektion i Java
Vi är medvetna om att vi i en given klass kan ändra dess egenskaper och metoder vid sammanställningstid och det är väldigt enkelt att göra det. Oavsett om egenskaperna och metoderna är anonyma eller har namn kan de ändras efter vår önskan under sammanställningstiden.
Men vi kan inte ändra dessa klasser eller metoder eller fält vid körning i farten. Med andra ord är det mycket svårt att ändra beteendet hos olika programmeringskomponenter vid körning speciellt för okända objekt.
Java-programmeringsspråk har en funktion som kallas 'Reflexion' som gör att vi kan ändra körtidsbeteendet för en klass, ett fält eller en metod vid körning.
Således kan en reflektion definieras som en ”Teknik för att inspektera och modifiera körtidsbeteendet för ett okänt objekt vid körningstid. Ett objekt kan vara en klass, ett fält eller en metod. ”
Reflection är ett ”Application Programming Interface” (API) som tillhandahålls av Java.
Processen 'Reflektion' visas nedan.
I ovanstående representation kan vi se att vi har ett okänt objekt. Sedan använder vi Reflection API på det här objektet. Som ett resultat kan vi ändra beteendet hos detta objekt vid körning.
Således kan vi använda Reflection API i våra program i syfte att ändra objektets beteende. Objekten kan vara allt som metoder, gränssnitt, klasser etc. Vi inspekterar dessa objekt och ändrar sedan deras beteende vid körning med reflektions-API.
I Java är 'java.lang' och 'java.lang.reflect' de två paketen som ger klasser för reflektion. Specialklassen 'java.lang.Class' tillhandahåller metoderna och egenskaperna för att extrahera metadata med vilka vi kan inspektera och ändra klassbeteendet.
Vi använder Reflection API som tillhandahålls av ovanstående paket för att ändra klassen och dess medlemmar inklusive fält, metoder, konstruktörer etc. vid körning. Ett kännetecken för Reflection API är att vi också kan manipulera privata datamedlemmar eller metoder i klassen.
Reflection API används huvudsakligen i:
- Reflektion används främst i felsökningsverktyg, JUnit och ramar för att inspektera och ändra beteendet vid körning.
- IDE (integrerad utvecklingsmiljö) T.ex. Eclipse IDE, NetBeans, etc.
- Testverktyg etc.
- Den används när din applikation har tredjepartsbibliotek och när du vill veta om de tillgängliga klasserna och metoderna.
Reflection API i Java
Med hjälp av Reflection API kan vi implementera reflektionen på följande enheter:
- Fält : Fältklassen har information som vi använder för att deklarera en variabel eller ett fält som en datatyp (int, dubbel, String, etc.), åtkomstmodifierare (privat, offentlig, skyddad, etc.), namn (identifierare) och värde.
- Metod : Metodklassen kan hjälpa oss att extrahera information som åtkomstmodifierare för metoden, metodåtergångstyp, metodnamn, metodparametertyper och undantagstyper som tas upp av metoden.
- Byggare : Konstruktörsklassen ger information om klasskonstruktören som inkluderar modifierare för konstruktöråtkomst, konstruktionsnamn och parametertyper.
- Redigera : Modifierklass ger oss information om en specifik accessmodifierare.
Alla ovanstående klasser är en del av paketet java.lang.reflect. Därefter diskuterar vi var och en av dessa klasser och använder programmeringsexempel för att visa reflektion över dessa klasser.
Låt oss först börja med klassen java.lang.Class.
java.lang.Class Class
Klassen innehåller all information och data om klasser och objekt vid körning. Detta är huvudklassen som används för reflektion.
Klassen java.lang.Class tillhandahåller:
- Metoder för att hämta klassmetadata vid körningstid.
- Metoder för att inspektera och modifiera beteendet hos en klass vid körning.
Skapa java.lang.Class-objekt
Vi kan skapa objekt av java.lang.Class med något av följande alternativ.
gratis mp3-låtar nedladdningsapp för android
# 1) .klassförlängning
Det första alternativet att skapa ett objekt av klass är att använda .class-tillägget.
Till exempel,om Test är en klass kan vi skapa ett klassobjekt enligt följande:
Class obj_test = Test.class;
Sedan kan vi använda obj_test för att utföra reflektion eftersom det här objektet kommer att ha all information om klasstestet.
# 2) forName () metod
forName () -metoden tar namnet på klassen som ett argument och returnerar klassobjektet.
Till exempel,objektet för testklassen kan skapas enligt följande:
class obj_test = Class.forName (“Test”);
# 3) getClas () metod
getClass () -metoden använder objekt från en klass för att få java.lang.Class-objektet.
Till exempel,överväga följande kod:
Test obj = new Test (); Class obj_test = obj.getClass ();
På första raden skapade vi ett objekt av testklassen. Sedan använde vi det här objektet 'metoden' getClass () 'för att få ett objekt obj_test av java.lang.Class.
Få Super Class & Access Modifiers
java.lang.class ger en metod “getSuperClass ()” som används för att få superklassen i vilken klass som helst.
På samma sätt ger den en metod getModifier () som returnerar klassens åtkomstmodifierare.
Nedanstående exempel visar 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 ovanstående programmeringsexempel definieras ett gränssnitt Person med en ensam metod 'display ()'. Sedan definierar vi en studentklass som implementerar persongränssnittet. I huvudmetoden använder vi metoden getClass () för att hämta klassobjektet och sedan komma åt föräldern eller superklassen för studentobjektet med metoden getSuperClass ().
Skaffa gränssnitt
Om klassen implementerar några gränssnitt kan vi få dessa gränssnittsnamn med getInterfaces () -metoden i java.lang.Class. För detta måste vi göra en reflektion över Java-klassen.
Nedanstående programmeringsexempel visar användningen 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(); } } }
Produktion
I ovanstående program har vi definierat två gränssnitt, dvs. djur och djur. Sedan definierar vi en klass Hund som implementerar båda dessa gränssnitt.
I huvudmetoden hämtar vi objektet till klass Dog i java.lang.Class för att utföra reflektion. Sedan använder vi metoden getInterfaces () för att hämta gränssnitten som implementeras av klassen Hund.
Reflektion: Få fältvärde
Som redan nämnts tillhandahåller paketet java.lang.reflect fältklassen som hjälper oss att återspegla fältets eller datamedlemmarna i klassen.
Nedan listas de metoder som tillhandahålls av fältklassen för reflektion av ett fält.
Metod | Beskrivning |
---|---|
getField ('fieldName') | Returnerar fältet (offentligt) med ett angivet fältnamn. |
getFields () | Returnerar alla offentliga fält (både för klass och superklass). |
getDeclaredFields () | Hämtar alla fält i klassen. |
getModifier () | Returnerar heltalsrepresentation av fältets åtkomstmodifierare. |
set (classObject, värde) | Tilldelar fältet det angivna värdet. |
få (classObject) | Hämtar fältvärde. |
setAccessible (boolean) | Gör privata fält tillgängliga genom att passera sant. |
getDeclaredField ('fieldName') | Returnerar fältet med ett angivet namn. |
Nedan följer två reflektionsexempel som visar reflektionen på det offentliga och privata området.
Java-programmet nedan visar reflektionen över ett offentligt fält.
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 detta program har vi förklarat en klass 'Student' med ett offentligt fält Studentnamn. Sedan använder vi API-gränssnittet i fältklassen, vi reflekterar över fältet Studentnamn och hämtar dess åtkomstmodifierare och värde.
Nästa program reflekterar över ett privat fält i klassen. Operationerna liknar förutom att det görs ett extra funktionsanrop för det privata fältet. Vi måste anropa setAccessible (true) för det privata fältet. Sedan utför vi reflektion över detta fält på ett liknande sätt som det offentliga fältet.
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
Reflektion: Metod
På samma sätt som klassens fält kan vi också reflektera över klassmetoder och ändra deras beteende under körning. För detta använder vi metodklassen för paketet java.lang.reflect.
Nedan listas funktionerna som tillhandahålls av metodklassen för reflektion av klassmetoden.
Metod | Beskrivning |
---|---|
getMethods () | Hämtar alla offentliga metoder som definierats i klassen och dess superklass. |
getDeclaredMethod () | Returnerar metoder som deklarerats i klassen. |
hämta namn() | Returnerar metodnamnen. |
getModifiers () | Returnerar heltalsrepresentation av metodens åtkomstmodifierare. |
getReturnType () | Returnerar metodens returtyp. |
Nedanstående exempel visar reflektionen av klassmetoder i Java med ovanstå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 programmet ovan ser vi att metoden getDeclaredMethods returnerar matrisen av metoder som deklarerats av klassen. Sedan itererar vi genom denna array och visar informationen för varje metod.
Reflektion: Konstruktör
Vi kan använda klassen 'Constructor' i paketet java.lang.reflect för att inspektera och modifiera konstruktörerna för en Java-klass.
Konstruktorklassen tillhandahåller följande metoder för detta ändamål.
Metod | Beskrivning |
---|---|
getConstructors () | Returnerar alla konstruktörer som deklarerats i klassen och dess superklass. |
getDeclaredConstructor () | Returnerar alla deklarerade konstruktörer. |
hämta namn() | Hämtar konstruktörens namn. |
getModifiers () | Returnerar heltalets representation av åtkomstmodifierare för konstruktörer. |
getParameterCount () | Returnerar det totala antalet parametrar för en konstruktör. |
Reflektionsexemplet nedan visar reflektionen av konstruktörer av en klass i Java. Som metodreflektion returnerar här också getDeclaredConstructors-metoden en rad konstruktörer för en klass. Sedan går vi igenom denna konstruktörsgrupp för att visa information om varje 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
Nackdelar med reflektion
Reflektion är kraftfull men bör inte användas urskillningslöst. Om det är möjligt att använda utan reflektion, är det att föredra att undvika att använda den.
Nedan finns några nackdelar med reflektion:
- Performance Overhead: Även om reflektion är en kraftfull funktion, har reflekterande operationer fortfarande långsammare prestanda än icke-reflekterande operationer. Därför bör vi undvika att använda reflektioner i prestandakritiska applikationer.
- Säkerhetsbegränsningar: Eftersom reflektion är en körtidsfunktion kan det krävas behörighet för körning. Så för applikationer som kräver att koden ska köras i en begränsad säkerhetsinställning, kan reflektion inte vara till någon nytta.
- Exponering av interner: Genom att använda reflektion kan vi komma åt privata fält och metoder i en klass. Således bryter reflektion abstraktion som kan göra koden oportabel och dysfunktionell.
Vanliga frågor
F # 1) Varför används reflektion i Java?
Svar: Med hjälp av reflektion kan vi inspektera klasser, gränssnitt, konstruktörer, fält och metoder vid körning, även om de är anonyma vid sammanställningstid. Denna inspektion gör att vi kan ändra beteendet hos dessa enheter under körning.
F # 2) Var används reflektion?
Svar: Reflektion används i skrivramar som samverkar med användardefinierade klasser, där programmeraren inte ens vet vad klasserna eller andra enheter kommer att vara.
F # 3) Är Java-reflektion långsam?
Svar: Ja, det är långsammare än icke-reflektionskoden.
F # 4) Är Java Reflection dåligt?
Svar: På ett sätt, ja. Först och främst tappar vi sammanställningstiden. Utan säkerhet i sammanställningstiden kan vi få körtidsfel som kan påverka slutanvändarna. Det blir också svårt att felsöka felet.
F # 5) Hur stoppar du en reflektion i Java?
Svar: Vi undviker helt enkelt att använda reflektion genom att skriva icke-reflektionsoperationer. Eller kanske kan vi använda några generiska mekanismer som en anpassad validering med reflektion.
Mer om Java-reflektion
paketet java.lang.reflect har klasserna och gränssnitten för reflektion. Och java.lang.class kan användas som en ingångspunkt för reflektionen.
Hur man får klassobjekten:
1. Om du har instans av ett objekt,
klass c = obj.getclass ();
2. Om du vet vilken typ av klassen,
klass c = typ.getClass ();
3. Om du vet klassnamnet,
Klass c = Class.forName (“com.demo.Mydemoclass”);
Hur får man klassmedlemmarna:
Klassmedlemmar är fält (klassvariabler) och metoder.
- getFields () - Används för att få alla fält utom privata fält.
- getDeclaredField () - Används för att få privata fält.
- getDeclaredFields () - Används för att få privata och offentliga fält.
- getMethods () - Används för att få alla metoder utom privata metoder.
- getDeclaredMethods () –Används för att få offentliga och privata metoder.
Demoprogram:
ReflectionHelper.java:
Det här är klassen där vi ska inspektera med hjälp av Reflection API.
webbplatser för att titta på anime gratis
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()); } }}
Slutsats
Denna handledning förklarade Reflection API i Java i detalj. Vi såg hur man utför reflektion av klasser, gränssnitt, fält, metoder och konstruktörer tillsammans med några nackdelar med reflektion.
Reflektion är en relativt avancerad funktion i Java men bör användas av programmerare som har ett fäste på språket. Det beror på att det kan orsaka oväntade fel och resultat om det inte används med försiktighet.
Även om reflektion är kraftfull, bör den användas försiktigt. Ändå kan vi med hjälp av reflektion utveckla applikationer som inte är medvetna om klasser och andra enheter fram till körtid.
=> Ta en titt på Java-nybörjarguiden här.
Rekommenderad läsning
- Java Scanner-klasshandledning med exempel
- Java-heltal och Java BigInteger-klass med exempel
- JAVA-handledning för nybörjare: 100+ praktiska Java-videohandledning
- Introduktion till Java-programmeringsspråk - Videohandledning
- Vad är Java Vector | Java Vector Class Tutorial med exempel
- Java-gränssnitt och abstrakt klasshandledning med exempel
- Java substring () Metod - Handledning med exempel
- Java Collections Framework (JCF) Tutorial