Java Tutorial Reflection API cu exemplu

⚡ Rezumat inteligent

Java API-ul Reflection analizează și modifică capabilitățile unei clase în timpul execuției, inclusiv câmpurile, metodele și constructorii acesteia. Această resursă explică pachetul java.lang.reflect, metodele cheie ale java.lang.Class și patru exemple care citesc metadatele unei clase, variabile, metode și constructori.

  • 🔍 Definiție: Reflection inspectează și modifică clasele și membrii acestora în timpul execuției, chiar și pe cei privati.
  • 📦 Pachet Reflect: Clasele Field, Method, Constructor și Modificator adună informații declarative despre membri.
  • 🏷️ Metode de clasă: getName(), getSuperclass(), getInterfaces() și getModifiers() returnează metadatele clasei principale.
  • 🧪 Exemple lucrate: Patru programe extracmetadatele t ale unei clase, variabile, metode și constructori.
  • ⚠️ Prudență: Reflection poate accesa membri privați și este mai lent, așa că folosește-l ca ultimă soluție.

Java Tutorial API Reflection

În ce este Reflecția Java?

Java Reflecția este procesul de analiză și modificare a tuturor capabilităților unei clase în timpul execuției. API-ul Reflection din Java este utilizat pentru a manipula o clasă și membrii acesteia, care includ câmpuri, metode, constructori etc., în timpul execuției.

Un avantaj al API-ului Reflection în Java este că poate manipula și membrii privați ai clasei.

Pachetul java.lang.reflect oferă numeroase clase pentru implementarea reflecției. Metodele clasei java.lang.Class sunt utilizate pentru a colecta metadatele complete ale unei anumite clase.

Clasă în pachetul java.lang.reflect

În continuare este o listă de diverse Java clase în pachetul java.lang.reflect pentru a implementa reflecția:

  • Camp: Această clasă este utilizată pentru a colecta informații declarative, cum ar fi tipul de date, modificatorul de acces, numele și valoarea unei variabile.
  • Metodă: Această clasă este utilizată pentru a colecta informații declarative, cum ar fi modificatorul de acces, tipul de returnare, numele, tipurile de parametri și tipul de excepție al unei metode.
  • Constructor: Această clasă este utilizată pentru a colecta informații declarative, cum ar fi modificatorul de acces, numele și tipurile de parametri ai unui constructor.
  • Modificator: Această clasă este utilizată pentru a aduna informații despre un anumit modificator de acces.

Metode utilizate în java.lang.Class

  • public String getName(): Returnează numele clasei.
  • Clasa publică getSuperclass(): Returnează referința superclasei.
  • Clasa publică[] getInterfaces(): Returnează o matrice de interfețe implementate de clasa specificată.
  • public int getModificatori(): Returnează o valoare întreagă reprezentând modificatorii clasei specificate, care trebuie transmisă ca parametru metodei „public static String toString(int i)” ce returnează specificatorul de acces pentru clasa dată.

Cum să obțineți informații complete despre o clasă

Pentru a obține informații despre variabile, metode și constructori ai unei clase, trebuie să creăm un obiect al clasei. Următorul exemplu prezintă diferite modalități de a crea un obiect al clasei „Class”:

Metode utilizate în java.lang.Class

public class Guru99ClassObjectCreation {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1 - By using Class.forName() method
        Class c1 = Class.forName("Guru99ClassObjectCreation");
        // 2 - By using getClass() method
        Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
        Class c2 = guru99Obj.getClass();
        // 3 - By using .class
        Class c3 = Guru99ClassObjectCreation.class;
    }
}

Exemplul 1: Cum se obțin metadatele clasei

Următorul exemplu arată cum se obțin metadate precum numele clasei, numele superclasei, interfețele implementate și modificatorii de acces ai unei clase.

Vom obține metadatele clasei de mai jos numite Guru99Base.class:

Obțineți metadatele clasei

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Numele clasei este: Guru99 de bază
  2. Modificatorii săi de acces sunt: ​​public și abstract
  3. Are interfețe implementate: Serializabil și Clonabil
  4. Întrucât nu a extins explicit nicio clasă, superclasa sa este: java.lang.Object

Clasa de mai jos va primi metadatele Guru99Base.class și afișează-l:

Obțineți metadatele clasei

import java.lang.reflect.Modifier;
public class Guru99GetclassMetaData {
    public static void main(String[] args) throws ClassNotFoundException {
        // Create Class object for Guru99Base.class
        Class<Guru99Base> guru99ClassObj = Guru99Base.class;

        // Print name of the class
        System.out.println("Name of the class is : " + guru99ClassObj.getName());

        // Print super class name
        System.out.println("Name of the super class is : " + guru99ClassObj.getSuperclass().getName());

        // Get the list of implemented interfaces using getInterfaces() method
        Class[] guru99InterfaceList = guru99ClassObj.getInterfaces();

        // Print the implemented interfaces using a for-each loop
        System.out.print("Implemented interfaces are : ");
        for (Class guru99class1 : guru99InterfaceList) {
            System.out.print(guru99class1.getName() + " ");
        }
        System.out.println();

        // Get access modifiers using getModifiers() and Modifier.toString()
        int guru99AccessModifier = guru99ClassObj.getModifiers();
        System.out.println("Access modifiers of the class are : " + Modifier.toString(guru99AccessModifier));
    }
}
  1. Afișează numele clasei folosind metoda getName().
  2. Afișează numele superclasei folosind metoda getSuperclass().getName().
  3. Afișați numele interfețelor implementate.
  4. Afișează modificatorii de acces utilizați de clasă.

Obțineți metadatele clasei

Obțineți metadatele clasei

Exemplul 2: Cum se obțin metadatele unei variabile

Următorul exemplu arată cum se obțin metadatele unei variabile.

Aici, creăm o clasă numită Guru99VariableMetaData.class cu câteva variabile:

package guru;
public class Guru99VariableMetaData {
    public static int guru99IntVar1 = 1111;
    static int guru99IntVar2 = 2222;
    static String guru99StringVar1 = "guru99.com";
    static String guru99StringVar2 = "Learning Reflection API";
}

Pași pentru a obține metadatele despre variabilele din clasa de mai sus:

  1. Creați obiectul de clasă al clasei de mai sus, adică, Guru99VariableMetaData.class, după cum urmează:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Obțineți metadatele sub forma unei matrice de câmpuri folosind getFields() or getDeclaredFields() metode după cum urmează:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

getFields() Metoda returnează metadatele variabilelor publice din clasa specificată, precum și din superclasa sa.

getDeclaredFields() Metoda returnează metadatele tuturor variabilelor doar din clasa specificată.

  1. Obțineți numele variabilelor folosind metoda „public String getName()”.
  2. Obțineți tipul de date al variabilelor folosind metoda „public Class getType()”.
  3. Obțineți valoarea variabilei folosind metoda „public xxx get(Field)”. Aici, xxx poate fi un octet, un short sau orice tip de valoare pe care dorim să o obținem.
  4. Obțineți modificatorii de acces ai variabilelor folosind metodele getModifiers() și Modifier.toString(int i).

Aici, scriem o clasă pentru a obține metadatele variabilelor prezente în clasă. Guru99VariableMetaData.class:

Obțineți metadatele variabilei

package guru;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Guru99VariableMetaDataTest {
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
        // Create Class object for Guru99VariableMetaData.class
        Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
        Class guru99ClassObjVar = guru99ClassVar.getClass();

        // Get the metadata of all the fields of the class
        Field[] guru99Field1 = guru99ClassObjVar.getDeclaredFields();

        // Print name, data types, access modifiers and values of the variables
        for (Field field : guru99Field1) {
            System.out.println("Variable name : " + field.getName());
            System.out.println("Datatype of the variable : " + field.getType());

            int guru99AccessModifiers = field.getModifiers();
            System.out.println("Access Modifiers of the variable : " + Modifier.toString(guru99AccessModifiers));
            System.out.println("Value of the variable : " + field.get(guru99ClassVar));
            System.out.println();
        }
    }
}
  1. A fost creat un obiect de clasă pentru Guru99VariableMetaData.class.
  2. Am obținut toate metadatele variabilelor dintr-un array de câmpuri.
  3. A afișat toate numele variabilelor din clasă Guru99VariableMetaData.class.
  4. A afișat toate tipurile de date ale variabilelor din clasă.
  5. A afișat toți modificatorii de acces ai variabilelor din clasă.
  6. A afișat valorile tuturor variabilelor din clasă.

Obțineți metadatele metodei

Obțineți metadatele metodei

Exemplul 3: Cum se obțin metadatele metodei

Următorul exemplu arată cum se obțin metadatele unei metode.

Aici, creăm o clasă numită Guru99MethodMetaData.class cu câteva metode:

Obțineți metadatele metodei

package guru;
import java.sql.SQLException;
public class Guru99MethodMetaData {

    public void guru99Add(int firstElement, int secondElement, String result)
    throws ClassNotFoundException, ClassCastException {
        System.out.println("Demo method for Reflection API");
    }
    public String guru99Search(String searchString)
    throws ArithmeticException, InterruptedException {
        System.out.println("Demo method for Reflection API");
        return null;
    }
    public void guru99Delete(String deleteString)
    throws SQLException {
        System.out.println("Demo method for Reflection API");
    }
}

Pași pentru obținerea metadatelor despre metodele din clasa de mai sus:

  1. Creați obiectul de clasă al clasei de mai sus, adică, Guru99MethodMetaData.class, după cum urmează:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Obțineți informații despre metode dintr-un array Method folosind metodele getMethods() și getDeclaredMethods() după cum urmează:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    getMethods() Metoda returnează metadatele metodelor publice din clasa specificată, precum și din superclasa sa. getDeclaredMethods() Metoda returnează metadatele tuturor metodelor doar din clasa specificată.

  3. Obțineți numele metodei folosind getName () metodă.
  4. Obțineți tipul de retur al metodei folosind getReturnType() metodă.
  5. Obțineți modificatori de acces ai metodelor care utilizează getModifiers() și Modificator.toString(int i) metode.
  6. Obțineți tipuri de parametri de metodă folosind getParameterTypes() metodă, care returnează un array de clase.
  7. Obține excepții generate folosind getExceptionTypes() metodă, care returnează un array de clase.

Aici, scriem o clasă pentru a obține metadatele metodelor prezente în clasă. Guru99MethodMetaData.class:

Obțineți metadatele metodei

package guru;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Guru99MethodMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99MethodMetaData.class
        Class guru99ClassObj = Guru99MethodMetaData.class;

        // Get the metadata of all the methods using getDeclaredMethods()
        Method[] guru99Methods = guru99ClassObj.getDeclaredMethods();

        for (Method method : guru99Methods) {
            System.out.println("Name of the method : " + method.getName());
            System.out.println("Return type of the method : " + method.getReturnType());

            int guru99ModifierList = method.getModifiers();
            System.out.println("Method access modifiers : " + Modifier.toString(guru99ModifierList));

            Class[] guru99ParamList = method.getParameterTypes();
            System.out.print("Method parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = method.getExceptionTypes();
            System.out.print("Exception thrown by method : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. A fost creat un obiect de clasă pentru Guru99MethodMetaData.class.
  2. Am obținut toate metadatele tuturor metodelor dintr-o matrice de metode.
  3. Afișează toate numele metodelor prezente în clasă.
  4. A afișat tipurile de returnare ale metodelor din clasă.
  5. A afișat toți modificatorii de acces ai metodelor din clasă.
  6. A afișat tipurile de parametri ai metodelor.
  7. A afișat excepțiile generate de metode.

Obțineți metadatele metodei

Obțineți metadatele metodei

Exemplul 4: Cum se obțin metadatele constructorilor

Următorul exemplu arată cum se obțin metadatele constructorilor.

Aici, creăm o clasă numită Guru99Constructor.class cu constructori diferiți:

Obțineți metadatele constructorilor

package guru;

import java.rmi.RemoteException;
import java.sql.SQLException;

public class Guru99Constructor {

    public Guru99Constructor(int no) throws ClassCastException, ArithmeticException { }
    public Guru99Constructor(int no, String name) throws RemoteException, SQLException { }
    public Guru99Constructor(int no, String name, String address) throws InterruptedException { }
}

Aici, scriem o clasă pentru a obține metadatele constructorilor prezenți în clasă. Guru99Constructor.class:

Obțineți metadatele constructorilor

package guru;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Guru99ConstructorMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99Constructor.class
        Class guru99Class = Guru99Constructor.class;

        // Get all the constructor information in the Constructor array
        Constructor[] guru99ConstructorList = guru99Class.getConstructors();

        for (Constructor constructor : guru99ConstructorList) {
            System.out.println("Constructor name : " + constructor.getName());

            int guru99Modifiers = constructor.getModifiers();
            System.out.println("Constructor modifier : " + Modifier.toString(guru99Modifiers));

            Class[] guru99ParamList = constructor.getParameterTypes();
            System.out.print("Constructor parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = constructor.getExceptionTypes();
            System.out.print("Exception thrown by constructors : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. A fost creat un obiect de clasă pentru Guru99Constructor.class.
  2. Am obținut toate metadatele tuturor constructorilor dintr-un array Constructor.
  3. A afișat toate numele constructorilor prezenți în clasă.
  4. A afișat toți modificatorii de acces ai constructorilor din clasă.
  5. A afișat tipurile de parametri ai constructorilor.
  6. A afișat excepțiile generate de constructori.

Obțineți metadatele constructorilor

Obțineți metadatele constructorilor

Întrebări frecvente

Reflection permite framework-urilor și instrumentelor de inteligență artificială să inspecteze și să instanțieze clasele în timpul execuției. Acesta alimentează injecția de dependențe, serializarea și maparea ORM.pingși încărcarea dinamică a pluginurilor fără a cunoaște clasele exacte la momentul compilării.

IA poate construi rapid o schelă de cod prin reflecție, dar ar trebui să o examinați cu atenție. Reflecția poate ocoli verificările de acces și poate introduce riscuri de securitate și performanță, așa că codul generat necesită testare și validare.

Reflecția este mai lentă decât apelurile directe de metodă, poate rupe încapsularea prin accesarea membrilor privați și poate cauza probleme de securitate și întreținere. Ar trebui utilizată numai atunci când nu este disponibilă o abordare mai simplă.

Da. Folosind setAccessible(true), reflection poate citi și modifica câmpuri private și poate invoca metode private. Acest lucru este puternic pentru testare și framework-uri, dar poate încălca încapsularea și poate crea probleme de securitate.

Rezumați această postare cu: