Java Tutoriel API Reflection avec exemple

โšก Rรฉsumรฉ intelligent

Java L'API de rรฉflexion analyse et modifie les capacitรฉs d'une classe ร  l'exรฉcution, notamment ses champs, ses mรฉthodes et ses constructeurs. Cette ressource explique le package java.lang.reflect, les principales mรฉthodes de java.lang.Class et prรฉsente quatre exemples de lecture des mรฉtadonnรฉes d'une classe, d'une variable, d'une mรฉthode et d'un constructeur.

  • ๐Ÿ” Dรฉfinition: La rรฉflexion permet d'inspecter et de modifier les classes et leurs membres lors de l'exรฉcution, mรชme les classes privรฉes.
  • ๐Ÿ“ฆ Pack Rรฉflรฉchir : Les classes Field, Method, Constructor et Modifier recueillent des informations dรฉclaratives sur leurs membres.
  • ๐Ÿท๏ธ Mรฉthodes de classe : getName(), getSuperclass(), getInterfaces() et getModifiers() renvoient les mรฉtadonnรฉes de classe de base.
  • ๐Ÿงช Exemples rรฉsolus : Quatre programmes extracmรฉtadonnรฉes d'une classe, de ses variables, de ses mรฉthodes et de ses constructeurs.
  • โš ๏ธ Prudence : Reflection permet d'accรฉder aux membres privรฉs et est plus lent, utilisez-le donc en dernier recours.

Java Tutoriel sur l'API de rรฉflexion

Qu'est-ce que la rรฉflexion dans Java?

Java La rรฉflexion est le processus d'analyse et de modification de toutes les capacitรฉs d'une classe lors de son exรฉcution. L'API de rรฉflexion dans Java est utilisรฉ pour manipuler une classe et ses membres, notamment les champs, les mรฉthodes, les constructeurs, etc., lors de l'exรฉcution.

Un des avantages de l'API de rรฉflexion dans Java Il peut รฉgalement manipuler les membres privรฉs de la classe.

Le package java.lang.reflect fournit de nombreuses classes pour implรฉmenter la rรฉflexion. Les mรฉthodes de la classe java.lang.Class permettent de rรฉcupรฉrer les mรฉtadonnรฉes complรจtes d'une classe donnรฉe.

Classe dans le package java.lang.reflect

Voici une liste de divers Java les classes dans le package java.lang.reflect pour implรฉmenter la rรฉflexion :

  • Champ: Cette classe sert ร  recueillir des informations dรฉclaratives telles que le type de donnรฉes, le modificateur d'accรจs, le nom et la valeur d'une variable.
  • Prรฉparation: Cette classe est utilisรฉe pour recueillir des informations dรฉclaratives telles que le modificateur d'accรจs, le type de retour, le nom, les types de paramรจtres et le type d'exception d'une mรฉthode.
  • Constructeur: Cette classe est utilisรฉe pour recueillir des informations dรฉclaratives telles que le modificateur d'accรจs, le nom et les types de paramรจtres d'un constructeur.
  • Modificateur: Cette classe sert ร  recueillir des informations sur un modificateur d'accรจs particulier.

Mรฉthodes utilisรฉes dans java.lang.Class

  • public String getName(): Renvoie le nom de la classe.
  • public Class getSuperclass(): Renvoie la rรฉfรฉrence de la superclasse.
  • public Class[] getInterfaces(): Renvoie un tableau d'interfaces implรฉmentรฉes par la classe spรฉcifiรฉe.
  • public int getModifiers(): Renvoie une valeur entiรจre reprรฉsentant les modificateurs de la classe spรฉcifiรฉe, qui doit รชtre passรฉe comme paramรจtre ร  la mรฉthode ยซ public static String toString(int i) ยป qui renvoie le spรฉcificateur d'accรจs pour la classe donnรฉe.

Comment obtenir des informations complรจtes sur une classe

Pour obtenir des informations sur les variablesPour utiliser les mรฉthodes et les constructeurs d'une classe, il est nรฉcessaire de crรฉer un objet de cette classe. L'exemple suivant illustre diffรฉrentes maniรจres de crรฉer un objet de la classe ยซ Class ยป :

Mรฉthodes utilisรฉes dans 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;
    }
}

Exemple 1 : Comment obtenir les mรฉtadonnรฉes dโ€™une classe

L'exemple suivant montre comment obtenir des mรฉtadonnรฉes telles que le nom de la classe, le nom de la superclasse, les interfaces implรฉmentรฉes et les modificateurs d'accรจs d'une classe.

Nous allons rรฉcupรฉrer les mรฉtadonnรฉes de la classe ci-dessous nommรฉe Guru99Base.class :

Obtenir les mรฉtadonnรฉes de la classe

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Le nom de la classe est : Guru99Base
  2. Ses modificateurs d'accรจs sont : public et abstract
  3. Il a implรฉmentรฉ des interfaces : sรฉrialisable et clonable
  4. Puisqu'elle n'รฉtend aucune classe explicitement, sa superclasse est : java.lang.Object

La classe ci-dessous rรฉcupรฉrera les mรฉtadonnรฉes de Guru99Base.class et imprimez-le :

Obtenir les mรฉtadonnรฉes de la classe

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. Affichez le nom de la classe en utilisant la mรฉthode getName().
  2. Affichez le nom de la superclasse en utilisant la mรฉthode getSuperclass().getName().
  3. Afficher les noms des interfaces implรฉmentรฉes.
  4. Afficher les modificateurs d'accรจs utilisรฉs par la classe.

Obtenir les mรฉtadonnรฉes de la classe

Obtenir les mรฉtadonnรฉes de la classe

Exemple 2 : Comment obtenir les mรฉtadonnรฉes dโ€™une variable

L'exemple suivant montre comment obtenir les mรฉtadonnรฉes d'une variable.

Ici, nous crรฉons une classe nommรฉe Guru99VariableMetaData.class avec quelques variables :

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";
}

ร‰tapes pour obtenir les mรฉtadonnรฉes sur les variables de la classe ci-dessus :

  1. Crรฉez l'objet de classe de la classe ci-dessus, c'est-ร -dire, Guru99VariableMetaData.class, comme ci-dessous :
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Rรฉcupรฉrez les mรฉtadonnรฉes sous forme de tableau de champs en utilisant getFields() or getDeclaredFields () mรฉthodes comme ci-dessous :
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

Le getFields() Cette mรฉthode renvoie les mรฉtadonnรฉes des variables publiques de la classe spรฉcifiรฉe ainsi que de sa superclasse.

Le getDeclaredFields () Cette mรฉthode renvoie uniquement les mรฉtadonnรฉes de toutes les variables de la classe spรฉcifiรฉe.

  1. Obtenez le nom des variables ร  l'aide de la mรฉthode ยซ public String getName() ยป.
  2. Obtenez le type de donnรฉes des variables ร  l'aide de la mรฉthode ยซ public Class getType() ยป.
  3. Rรฉcupรฉrez la valeur de la variable ร  l'aide de la mรฉthode ยซ public xxx get(Field) ยป. Ici, xxx peut รชtre un octet, un entier court ou tout autre type de valeur ร  rรฉcupรฉrer.
  4. Obtenez les modificateurs d'accรจs des variables ร  l'aide des mรฉthodes getModifiers() et Modifier.toString(int i).

Ici, nous รฉcrivons une classe pour obtenir les mรฉtadonnรฉes des variables prรฉsentes dans la classe. Guru99VariableMetaData.class :

Obtenir les mรฉtadonnรฉes de la variable

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. Crรฉation d'un objet de classe pour Guru99VariableMetaData.class.
  2. J'ai rรฉcupรฉrรฉ toutes les mรฉtadonnรฉes des variables dans un tableau de champs.
  3. J'ai imprimรฉ tous les noms de variables de la classe. Guru99VariableMetaData.class.
  4. Afficher tous les types de donnรฉes des variables de la classe.
  5. J'ai imprimรฉ tous les modificateurs d'accรจs des variables de la classe.
  6. Les valeurs de toutes les variables de la classe ont รฉtรฉ affichรฉes.

Obtenir les mรฉtadonnรฉes de la mรฉthode

Obtenir les mรฉtadonnรฉes de la mรฉthode

Exemple 3 : Comment obtenir les mรฉtadonnรฉes dโ€™une mรฉthode

L'exemple suivant montre comment obtenir les mรฉtadonnรฉes d'une mรฉthode.

Ici, nous crรฉons une classe nommรฉe Guru99MethodMetaData.class avec quelques mรฉthodes :

Obtenir les mรฉtadonnรฉes de la mรฉthode

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");
    }
}

ร‰tapes pour obtenir les mรฉtadonnรฉes relatives aux mรฉthodes de la classe ci-dessus :

  1. Crรฉez l'objet de classe de la classe ci-dessus, c'est-ร -dire, Guru99MethodMetaData.class, comme ci-dessous :
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Obtenez les informations sur les mรฉthodes dans un tableau Method en utilisant les mรฉthodes getMethods() et getDeclaredMethods() comme ci-dessous :
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    Le getMethods() Cette mรฉthode renvoie les mรฉtadonnรฉes des mรฉthodes publiques de la classe spรฉcifiรฉe ainsi que de sa superclasse. getDeclaredMethods() Cette mรฉthode renvoie uniquement les mรฉtadonnรฉes de toutes les mรฉthodes de la classe spรฉcifiรฉe.

  3. Obtenez le nom de la mรฉthode en utilisant getName () mรฉthode.
  4. Obtenez le type de retour de la mรฉthode en utilisant getReturnType() mรฉthode.
  5. Obtenez les modificateurs d'accรจs des mรฉthodes en utilisant getModifiers() et Modifier.toString(int i) mรฉthodes.
  6. Obtenez les types de paramรจtres de mรฉthode en utilisant getParameterTypes() mรฉthode, qui renvoie un tableau de classes.
  7. Rรฉcupรฉrez les exceptions levรฉes en utilisant getExceptionTypes() mรฉthode, qui renvoie un tableau de classes.

Ici, nous รฉcrivons une classe pour obtenir les mรฉtadonnรฉes des mรฉthodes prรฉsentes dans la classe. Guru99MethodMetaData.class :

Obtenir les mรฉtadonnรฉes de la mรฉthode

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. Crรฉation d'un objet de classe pour Guru99MethodMetaData.class.
  2. J'ai rรฉcupรฉrรฉ toutes les mรฉtadonnรฉes de toutes les mรฉthodes dans un tableau de mรฉthodes.
  3. Affiche tous les noms de mรฉthodes prรฉsents dans la classe.
  4. Affichage des types de retour des mรฉthodes de la classe.
  5. J'ai imprimรฉ tous les modificateurs d'accรจs des mรฉthodes de la classe.
  6. Affichage des types de paramรจtres des mรฉthodes.
  7. Les exceptions levรฉes par les mรฉthodes ont รฉtรฉ imprimรฉes.

Obtenir les mรฉtadonnรฉes de la mรฉthode

Obtenir les mรฉtadonnรฉes de la mรฉthode

Exemple 4 : Comment obtenir les mรฉtadonnรฉes des constructeurs

L'exemple suivant montre comment obtenir les mรฉtadonnรฉes des constructeurs.

Ici, nous crรฉons une classe nommรฉe Guru99Constructor.class avec diffรฉrents constructeurs :

Obtenir les mรฉtadonnรฉes des constructeurs

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 { }
}

Ici, nous รฉcrivons une classe pour obtenir les mรฉtadonnรฉes des constructeurs prรฉsents dans la classe. Guru99Constructeur.class :

Obtenir les mรฉtadonnรฉes des constructeurs

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. Crรฉation d'un objet de classe pour Guru99Constructeur.classe.
  2. J'ai rรฉcupรฉrรฉ toutes les mรฉtadonnรฉes de tous les constructeurs dans un tableau Constructor.
  3. Affiche tous les noms des constructeurs prรฉsents dans la classe.
  4. J'ai imprimรฉ tous les modificateurs d'accรจs des constructeurs de la classe.
  5. Affichage des types de paramรจtres des constructeurs.
  6. J'ai imprimรฉ les exceptions levรฉes par les constructeurs.

Obtenir les mรฉtadonnรฉes des constructeurs

Obtenir les mรฉtadonnรฉes des constructeurs

FAQ

La rรฉflexion permet aux frameworks et aux outils d'IA d'inspecter et d'instancier des classes ร  l'exรฉcution. Elle prend en charge l'injection de dรฉpendances, la sรฉrialisation et la gestion des ORM.pinget le chargement dynamique de plugins sans connaรฎtre les classes exactes au moment de la compilation.

L'IA peut gรฉnรฉrer rapidement du code de rรฉflexion, mais il convient de l'examiner attentivement. La rรฉflexion peut contourner les contrรดles d'accรจs et engendrer des risques de sรฉcuritรฉ et de performance ; le code gรฉnรฉrรฉ doit donc รชtre testรฉ et validรฉ.

La rรฉflexion est plus lente que les appels de mรฉthode directs, peut rompre l'encapsulation en accรฉdant ร  des membres privรฉs et peut engendrer des problรจmes de sรฉcuritรฉ et de maintenance. Elle ne devrait รชtre utilisรฉe qu'en dernier recours.

Oui. L'utilisation de `setAccessible(true)` permet ร  la rรฉflexion de lire et de modifier les champs privรฉs, ainsi que d'appeler des mรฉthodes privรฉes. C'est trรจs utile pour les tests et les frameworks, mais cela peut compromettre l'encapsulation et engendrer des problรจmes de sรฉcuritรฉ.

Rรฉsumez cet article avec :