java reflection tutorial with examples
Acest tutorial video explică ce este Reflection și cum să-l implementați folosind Reflection API:
Reflecția în Java este de a inspecta și schimba comportamentul unui program în timpul rulării.
Cu ajutorul acestui API de reflecție, puteți inspecta clase, constructori, modificatori, câmpuri, metode și interfețe în timpul rulării. De exemplu, puteți obține numele clasei sau puteți obține detalii despre membrii privați ai clasei.
Citiți întregul nostru Seria de antrenament JAVA pentru mai multe informații despre conceptele Java.
Iată un tutorial video despre Java Reflection:
Ce veți învăța:
Reflecție în Java
Suntem conștienți de faptul că într-o anumită clasă îi putem modifica proprietățile și metodele la momentul compilării și este foarte ușor să o faci. Indiferent dacă proprietățile și metodele sunt anonime sau au nume, ele pot fi schimbate după bunul plac în timpul compilării.
Dar nu putem schimba aceste clase, metode sau câmpuri în timpul rulării din mers. Cu alte cuvinte, este foarte dificil să schimbați comportamentul diferitelor componente de programare în timpul rulării, în special pentru obiectele necunoscute.
Limbajul de programare Java oferă o caracteristică numită 'Reflecţie' care ne permite să modificăm comportamentul de rulare al unei clase sau câmpuri sau metode în timpul rulării.
Astfel o Reflecție poate fi definită ca o „Tehnică de inspectare și modificare a comportamentului de rulare al unui obiect necunoscut în timpul rulării. Un obiect poate fi o clasă, un câmp sau o metodă. ”
Reflection este o „Interfață de programare a aplicației” (API) furnizată de Java.
Procesul „Reflecție” este descris mai jos.
În reprezentarea de mai sus, putem vedea că avem un obiect necunoscut. Apoi, folosim API-ul Reflection pe acest obiect. Ca rezultat, putem modifica comportamentul acestui obiect în timpul rulării.
Astfel, putem folosi API-ul Reflection în programele noastre în scopul modificării comportamentului obiectului. Obiectele pot fi de genul metode, interfețe, clase etc. Inspectăm aceste obiecte și apoi le schimbăm comportamentul în timpul rulării folosind API-ul de reflecție.
În Java, „java.lang” și „java.lang.reflect” sunt cele două pachete care oferă clase pentru reflecție. Clasa specială „java.lang.Class” oferă metode și proprietăți pentru extragerea metadatelor folosind care putem inspecta și modifica comportamentul clasei.
Folosim API-ul Reflection furnizat de pachetele de mai sus pentru a modifica clasa și membrii acesteia, incluzând câmpuri, metode, constructori etc. în timpul rulării. O caracteristică distinctivă a API-ului Reflection este că putem manipula și membrii datelor private sau metodele clasei.
API-ul Reflection este utilizat în principal în:
- Reflecția este utilizată în principal în instrumentele de depanare, JUnit și cadre pentru a inspecta și schimba comportamentul în timpul rulării.
- IDE (mediu de dezvoltare integrat) De exemplu. Eclipse IDE, NetBeans etc.
- Instrumente de testare etc.
- Se folosește atunci când aplicația dvs. are biblioteci terțe și când doriți să aflați despre clasele și metodele disponibile.
Reflection API În Java
Folosind Reflection API, putem implementa reflecția asupra următoarelor entități:
- Camp : Clasa Field conține informații pe care le folosim pentru a declara o variabilă sau un câmp precum un tip de date (int, double, String etc.), modificator de acces (privat, public, protejat etc.), nume (identificator) și valoare.
- Metodă : Clasa Metodă ne poate ajuta să extragem informații cum ar fi modificatorul de acces al metodei, tipul de returnare a metodei, numele metodei, tipurile de parametri ale metodei și tipurile de excepții generate de metodă.
- Constructor : Clasa constructor oferă informații despre constructorul clasei, care include modificatorul de acces al constructorului, numele constructorului și tipurile de parametri.
- Editați | × : Clasa Modifier ne oferă informații despre un modificator de acces specific.
Toate clasele de mai sus fac parte din pachetul java.lang.reflect. În continuare, vom discuta fiecare dintre aceste clase și vom folosi exemple de programare pentru a demonstra reflecția asupra acestor clase.
Să începem mai întâi cu clasa java.lang.Class.
java.lang.Class Class
Clasa java.lang.Clasează toate informațiile și datele despre clase și obiecte în timpul rulării. Aceasta este principala clasă utilizată pentru reflecție.
Clasa java.lang.Class oferă:
- Metode de recuperare a metadatelor clasei în timpul rulării.
- Metode de inspectare și modificare a comportamentului unei clase în timpul rulării.
Creați obiecte java.lang.Class
Putem crea obiecte din java.lang.Class folosind una dintre următoarele opțiuni.
întrebări și răspunsuri la interviu de asistență tehnică pentru cei care se pregătesc pentru noi
# 1) .extensie de clasă
Prima opțiune pentru a crea un obiect al clasei este folosind extensia .class.
De exemplu,dacă Test este o clasă, atunci putem crea un obiect Class după cum urmează:
Class obj_test = Test.class;
Apoi putem folosi obiect_test pentru a efectua reflecția, deoarece acest obiect va avea toate informațiile despre testul clasei.
# 2) metoda forName ()
metoda forName () ia numele clasei ca argument și returnează obiectul Class.
De exemplu,obiectul clasei Test poate fi creat după cum urmează:
class obj_test = Class.forName (“Test”);
# 3) metoda getClas ()
Metoda getClass () folosește obiectul unei clase pentru a obține obiectul java.lang.Class.
De exemplu,ia în considerare următoarea bucată de cod:
Test obj = new Test (); Class obj_test = obj.getClass ();
În prima linie, am creat un obiect din clasa Test. Apoi, folosind acest obiect, am numit metoda „getClass ()” pentru a obține un obiect obj_test al java.lang.Class.
Obțineți modificatori Super Class și Access
java.lang.class oferă o metodă „getSuperClass ()” care este utilizată pentru a obține superclasa oricărei clase.
În mod similar, oferă o metodă getModifier () care returnează modificatorul de acces al clasei.
Exemplul de mai jos demonstrează metoda 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(); } } }
Ieșire
În exemplul de programare de mai sus, o interfață Persoană este definită cu o metodă solitară „display ()”. Apoi definim o clasă Student care implementează interfața persoană. În metoda principală, folosim metoda getClass () pentru a recupera obiectul Class și apoi accesăm părintele sau superclasa obiectului Student folosind metoda getSuperClass ().
Obțineți interfețe
Dacă clasa implementează unele interfețe, atunci putem obține aceste nume de interfețe folosind metoda getInterfaces () a java.lang.Class. Pentru aceasta, trebuie să facem o reflecție asupra clasei Java.
Exemplul de programare de mai jos descrie utilizarea metodei getInterfaces () în 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(); } } }
Ieșire
În programul de mai sus, am definit două interfețe, adică Animale și Animale de companie. Apoi definim o clasă Dog, care implementează ambele interfețe.
În metoda principală, recuperăm obiectul clasei Dog în java.lang.Class pentru a efectua reflecția. Apoi folosim metoda getInterfaces () pentru a prelua interfețele implementate de clasa Dog.
Reflecție: obțineți valoarea câmpului
După cum sa menționat deja, pachetul java.lang.reflect oferă clasa Field care ne ajută să reflectăm câmpul sau membrii clasei.
Mai jos sunt enumerate metodele furnizate de clasa Câmp pentru reflectarea unui câmp.
Metodă | Descriere |
---|---|
getField ('fieldName') | Returnează câmpul (public) cu un nume de câmp specificat. |
getFields () | Returnează toate câmpurile publice (atât pentru clasă, cât și pentru superclasă). |
getDeclaredFields () | Preluează toate câmpurile clasei. |
getModifier () | Returnează reprezentarea întreagă a modificatorului de acces al câmpului. |
set (classObject, valoare) | Atribuie câmpului valoarea specificată. |
get (classObject) | Preluează valoarea câmpului. |
setAccessible (boolean) | Faceți accesibil câmpului privat prin trecerea la adevărat |
getDeclaredField ('fieldName') | Returnează câmpul cu un nume specificat. |
Mai jos sunt prezentate două exemple de reflecție care demonstrează reflecția asupra domeniului public și privat.
Programul Java de mai jos demonstrează reflectarea asupra unui câmp public.
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(); } } }
Ieșire
În acest program, am declarat o clasă „Student” având un câmp public StudentName. Apoi, folosind interfața API a clasei Field, efectuăm o reflecție asupra câmpului StudentName și îi preluăm modificatorul de acces și valoarea.
Următorul program efectuează reflecții asupra unui domeniu privat al clasei. Operațiunile sunt similare, cu excepția faptului că există o singură funcție suplimentară efectuată pentru câmpul privat. Trebuie să apelăm setAccessible (true) pentru câmpul privat. Apoi efectuăm o reflecție asupra acestui câmp într-un mod similar cu cel public.
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(); } } }
Ieșire
Reflecție: Metodă
Similar câmpurilor clasei, putem efectua, de asemenea, o reflecție asupra metodelor clasei și le putem modifica comportamentul în timpul rulării. Pentru aceasta, folosim clasa Method a pachetului java.lang.reflect.
Mai jos sunt enumerate funcțiile furnizate de clasa Metodă pentru reflectarea metodei clasei.
Metodă | Descriere |
---|---|
getMethods () | Preluează toate metodele publice definite în clasă și în superclasa sa. |
getDeclaredMethod () | Returnează metodele declarate în clasă. |
getName () | Returnează numele metodelor. |
getModifiers () | Returnează reprezentarea întreagă a modificatorului de acces al metodei. |
getReturnType () | Returnează tipul de returnare a metodei. |
Exemplul de mai jos arată reflectarea metodelor de clasă în Java folosind API-urile de mai sus.
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(); } } }
Ieșire
În programul de mai sus, vedem că metoda getDeclaredMethods returnează matricea de metode declarate de clasă. Apoi iterăm prin această matrice și afișăm informațiile fiecărei metode.
Reflecție: Constructor
Putem folosi clasa „Constructor” a pachetului java.lang.reflect pentru a inspecta și modifica constructorii unei clase Java.
Clasa constructor oferă următoarele metode în acest scop.
Metodă | Descriere |
---|---|
getConstructors () | Returnează toți constructorii declarați în clasă și superclasa sa. |
getDeclaredConstructor () | Returnează toți constructorii declarați. |
getName () | Preluează numele constructorului. |
getModifiers () | Returnează reprezentarea întreagă a modificatorului de acces al constructorilor. |
getParameterCount () | Returnează numărul total de parametri pentru un constructor. |
Exemplul de reflecție de mai jos demonstrează reflectarea constructorilor unei clase în Java. Ca și reflecția metodei, aici și metoda getDeclaredConstructors returnează o serie de constructori pentru o clasă. Apoi traversăm această matrice de constructori pentru a afișa informații despre fiecare constructor.
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(); } } }
Ieșire
Dezavantaje ale reflecției
Reflecția este puternică, dar nu ar trebui folosită fără discriminare. Dacă este posibil să funcționați fără a utiliza reflexia, atunci este de preferat să evitați utilizarea acesteia.
Mai jos sunt prezentate câteva dezavantaje ale reflecției:
- Performanță generală: Deși reflexia este o caracteristică puternică, operațiunile reflectorizante au încă o performanță mai lentă decât operațiile nereflectante. Prin urmare, ar trebui să evităm utilizarea reflexiilor în aplicații critice pentru performanță.
- Restricții de securitate: Deoarece reflectarea este o caracteristică de execuție, ar putea necesita permisiuni în timpul rulării. Deci, pentru aplicațiile care necesită executarea codului într-o setare de securitate restricționată, este posibil ca reflectarea să nu fie de nici un folos.
- Expunerea internelor: Prin utilizarea reflecției, putem accesa câmpuri și metode private într-o clasă. Astfel, reflecția sparge abstractizarea care ar putea face codul neportabil și disfuncțional.
întrebări frecvente
Q # 1) De ce se utilizează Reflection în Java?
Răspuns: Folosind reflecția, putem inspecta clase, interfețe, constructori, câmpuri și metode în timpul rulării, chiar dacă acestea sunt anonime la compilare. Această inspecție ne permite să modificăm comportamentul acestor entități în timpul rulării.
Q # 2) Unde se folosește Reflection?
Răspuns: Reflecția este utilizată în scrierea cadrelor care interoperă cu clasele definite de utilizator, în care programatorul nici măcar nu știe care vor fi clasele sau alte entități.
Q # 3) Java Reflection este lent?
Răspuns: Da, este mai lent decât codul de non-reflexie.
Q # 4) Este Java Reflection rău?
Răspuns: Într-un fel, da. În primul rând, pierdem siguranța la compilare. Fără siguranță în timpul compilării, s-ar putea să aparem erori în timpul rulării care ar putea afecta utilizatorii finali. De asemenea, va fi dificil să depanați eroarea.
Q # 5) Cum opriți o reflecție în Java?
Răspuns: Pur și simplu evităm utilizarea reflexiei scriind operații de non-reflexie. Sau poate putem folosi unele mecanisme generice, cum ar fi o validare personalizată cu reflecție.
Mai multe despre Java Reflection
pachetul java.lang.reflect are clasele și interfețele pentru a reflecta. Și java.lang.class poate fi folosit ca punct de intrare pentru reflecție.
Cum să obțineți obiectele clasei:
1. Dacă aveți instanța unui obiect,
clasa c = obj.getclass ();
2. Dacă cunoașteți tipul clasei,
clasa c = type.getClass ();
3. Dacă știți numele clasei,
Clasa c = Class.forName („com.demo.Mydemoclass”);
Cum să obțineți membrii clasei:
Membrii clasei sunt câmpuri (variabile de clasă) și metode.
- getFields () - Folosit pentru a obține toate câmpurile, cu excepția câmpurilor private.
- getDeclaredField () - Folosit pentru a obține câmpurile private.
- getDeclaredFields () - Folosit pentru a obține câmpurile private și publice.
- getMethods () - Folosit pentru a obține toate metodele, cu excepția metodelor private.
- getDeclaredMethods () –Se folosește pentru a obține metode publice și private.
Programe demonstrative:
ReflectionHelper.java:
Aceasta este clasa în care vom inspecta folosind API-ul de reflecție.
odihnitoare servicii web java întrebări de interviu
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()); } }}
Concluzie
Acest tutorial a explicat în detaliu API-ul Reflection în Java. Am văzut cum să realizăm reflectarea claselor, interfețelor, câmpurilor, metodelor și constructorilor împreună cu câteva dezavantaje ale reflectării.
Reflecția este o caracteristică relativ avansată în Java, dar ar trebui să fie utilizată de programatorii care au un punct forte asupra limbajului. Acest lucru se datorează faptului că ar putea provoca erori și rezultate neașteptate dacă nu este utilizat cu precauție.
Deși reflexia este puternică, ar trebui folosită cu atenție. Cu toate acestea, folosind reflecția putem dezvolta aplicații care nu știu de clase și alte entități până la runtime.
=> Consultați aici Ghidul pentru începători Java.
Lectură recomandată
- Tutorial de clasă Java Scanner cu exemple
- Java Integer și Java BigInteger Class cu exemple
- Tutorial JAVA pentru începători: peste 100 de cursuri video Java practice
- Introducere în limbajul de programare Java - Video Tutorial
- Ce este Java Vector | Tutorial Java Vector Class cu exemple
- Interfață Java și tutorial de clasă abstractă cu exemple
- Metoda Java substring () - Tutorial cu exemple
- Tutorial Java Collections Framework (JCF)