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: