Classes liées à la réflexion Java et principes sous-jacents

1. Classes de base de réflexion Java :

1. Classe :

Représente une instance d'une classe Java et peut être utilisé pour obtenir des informations sur la classe, telles que le nom de la classe, la classe parent, l'interface, les champs, les méthodes, etc. Vous pouvez utiliser la méthode Class.forName() pour obtenir un objet Class basé sur le nom de la classe, ou utiliser la méthode getClass() de l'objet pour obtenir un objet Class.

Voici un exemple de code simple qui montre comment utiliser la réflexion pour obtenir des informations sur la classe :

public class Main {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            // 使用Class.forName()方法获取Class对象
            Class<?> clazz = Class.forName("com.example.MyClass");

            // 获取类名
            String className = clazz.getName();
            System.out.println("Class Name: " + className);

            // 获取父类
            Class<?> superClass = clazz.getSuperclass();
            System.out.println("Super Class: " + superClass.getName());

            // 获取接口
            Class<?>[] interfaces = clazz.getInterfaces();
            System.out.println("Implemented Interfaces:");
            for (Class<?> interfaceClass : interfaces) {
    
    
                System.out.println(interfaceClass.getName());
            }

            // 获取字段
            Field[] fields = clazz.getDeclaredFields();
            System.out.println("Fields:");
            for (Field field : fields) {
    
    
                System.out.println(field.getName());
            }

            // 获取方法
            Method[] methods = clazz.getDeclaredMethods();
            System.out.println("Methods:");
            for (Method method : methods) {
    
    
                System.out.println(method.getName());
            }

            // 获取构造器
            Constructor<?>[] constructors = clazz.getDeclaredConstructors();
            System.out.println("Constructors:");
            for (Constructor<?> constructor : constructors) {
    
    
                System.out.println(constructor.getName());
            }
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        }
    }
}

class MyClass extends BaseClass implements MyInterface {
    
    
    private int id;
    public String name;

    public MyClass(int id, String name) {
    
    
        this.id = id;
        this.name = name;
    }

    public void printInfo() {
    
    
        System.out.println("ID: " + id);
        System.out.println("Name: " + name);
    }
}

class BaseClass {
    
    
    // 父类
}

interface MyInterface {
    
    
    // 接口
}

Résultat de sortie :

Class Name: com.example.MyClass
Super Class: com.example.BaseClass
Implemented Interfaces:
com.example.MyInterface
Fields:
id
name
Methods:
printInfo
Constructors:
com.example.MyClass

2. Classe constructeur :

Représente la méthode constructeur d'une classe, qui peut être utilisée pour créer des instances de la classe. Vous pouvez utiliser la méthode getConstructor() ou getDeclaredConstructor() de la classe Class pour obtenir l'objet Constructor, puis utiliser la méthode newInstance() pour créer une instance.

Voici un exemple simple montrant comment utiliser la méthode constructeur pour créer une instance d'une classe :

import java.lang.reflect.Constructor;

class MyClass {
    
    
    private String name;

    public MyClass(String name) {
    
    
        this.name = name;
    }

    public void printName() {
    
    
        System.out.println("Name: " + name);
    }
}

public class Main {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 获取 MyClass 类的构造方法
        Constructor<MyClass> constructor = MyClass.class.getConstructor(String.class);

        // 使用构造方法创建类的实例
        MyClass myClass = constructor.newInstance("John");

        // 调用实例方法
        myClass.printName();
    }
}

Dans l'exemple ci-dessus, nous utilisons d'abord MyClass.class.getConstructor(String.class) pour obtenir l'objet constructeur de la classe MyClass. Le constructeur accepte un paramètre de type String. Ensuite, nous utilisons constructor.newInstance("John") pour créer une instance, et le paramètre "John" sera transmis en tant que paramètre de constructeur. Enfin, nous appelons la méthode d'instance printName() pour imprimer le nom de l'instance.

3. Classe de terrain :

Représente un champ d'une classe qui peut être utilisé pour obtenir et définir la valeur du champ. Vous pouvez utiliser la méthode getField() ou la méthode getDeclaredField() de la classe Class pour obtenir l'objet Field, puis utiliser la méthode get() pour obtenir la valeur du champ, ou utiliser la méthode set() pour définir la valeur du champ.

Voici un exemple simple montrant comment utiliser les champs pour obtenir et définir la valeur d'un champ :

import java.lang.reflect.Field;

class MyClass {
    
    
    public String name;
    private int age;

    public MyClass(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    public void printInfo() {
    
    
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
    }
}

public class Main {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 创建 MyClass 实例
        MyClass myClass = new MyClass("John", 25);

        // 获取 MyClass 类的 name 字段
        Field nameField = MyClass.class.getField("name");

        // 获取 MyClass 类的 age 字段
        Field ageField = MyClass.class.getDeclaredField("age");
        ageField.setAccessible(true); // 设置私有字段可访问

        // 获取字段的值
        String nameValue = (String) nameField.get(myClass);
        int ageValue = (int) ageField.get(myClass);

        System.out.println("Name: " + nameValue);
        System.out.println("Age: " + ageValue);

        // 设置字段的值
        nameField.set(myClass, "Alice");
        ageField.set(myClass, 30);

        myClass.printInfo();
    }
}

Dans l'exemple ci-dessus, nous avons créé une instance de la classe MyClass et utilisé la méthode getField() pour obtenir l'objet Field du champ nom, et utilisé la méthode getDeclaredField() pour obtenir l'objet Field du champ age. La méthode getDeclaredField() peut obtenir des champs privés, mais les champs privés sont inaccessibles par défaut, nous devons donc appeler setAccessible(true) pour rendre les champs privés accessibles.

Ensuite, nous avons utilisé la méthode get() pour obtenir respectivement les valeurs du champ nom et du champ âge, et avons utilisé la méthode set() pour définir la valeur du champ nom sur "Alice" et la valeur du champ âge à 30. Enfin, nous appelons la méthode printInfo() pour imprimer la valeur du champ et vérifier si la valeur du champ a été modifiée. Notez qu'une conversion de type est requise pour obtenir et définir la valeur du champ.

4. Classe de méthode :

Représente une méthode de classe qui peut être utilisée pour appeler des méthodes. Vous pouvez utiliser la méthode getMethod() ou getDeclaredMethod() de la classe Class pour obtenir l'objet Method, puis utiliser la méthode Invocation() pour appeler la méthode.

Voici un exemple de code qui utilise la réflexion pour appeler une méthode d'une classe :

import java.lang.reflect.Method;

class MyClass {
    
    
    public void myMethod() {
    
    
        System.out.println("调用了myMethod方法");
    }
}

public class Main {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 获取MyClass类的Class对象
        Class<?> clazz = MyClass.class;

        // 获取myMethod方法的Method对象
        Method method = clazz.getMethod("myMethod");

        // 创建MyClass类的实例
        MyClass myObj = new MyClass();

        // 调用myMethod方法
        method.invoke(myObj);
    }
}

Résultat de sortie :

调用了myMethod方法

Dans le code ci-dessus, nous obtenons d'abord l'objet Class de la classe MyClass via MyClass.class. Utilisez ensuite la méthode getMethod() pour transmettre le nom de la méthode afin d'obtenir l'objet Method de la méthode myMethod.

Ensuite, nous créons une instance de la classe MyClass myObj.

Enfin, nous utilisons la méthode Invoke() pour appeler la méthode myMethod, en passant myObj comme appelant de la méthode. Cela appelle avec succès la méthode myMethod.

Il est à noter que si la méthode myMethod est une méthode privée ou une méthode héritée de la classe parent, vous devez utiliser la méthode getDeclaredMethod() pour obtenir l'objet Method. Et avant d'appeler la méthode Invoke(), vous devez appeler setAccessible(true) pour définir l'accessibilité de la méthode.

2. Le principe sous-jacent de la réflexion

  1. Lors de l'exécution d'un programme Java, le code source doit d'abord être compilé pour générer le fichier de bytecode correspondant (fichier .class). Ensuite, la JVM chargera ces fichiers de bytecode et créera les informations de classe correspondantes dans la zone des méthodes, y compris le nom de la classe, la classe parent, l'interface, les champs, les méthodes, etc.

  2. La réflexion consiste à réaliser des opérations dynamiques sur les classes en obtenant ces informations de classe. En obtenant l'objet Class d'une classe, vous pouvez obtenir le nom, la classe parent, l'interface et d'autres informations de la classe.
    Grâce aux méthodes de l'objet Class, vous pouvez obtenir le constructeur, les champs, les méthodes et d'autres informations sur les membres de la classe, et vous pouvez créer dynamiquement des objets, appeler des méthodes, accéder aux champs, etc.

  3. Le mécanisme de réflexion permet au programme d'obtenir et d'exploiter dynamiquement les informations de classe au moment de l'exécution sans déterminer la structure de la classe au moment de la compilation. Cela facilite le développement de frameworks, le proxy dynamique, la lecture de fichiers de configuration, etc. Cependant, il convient de noter que l'utilisation de la réflexion peut entraîner certaines pertes de performances. Elle doit donc être utilisée avec prudence dans des scénarios exigeant des performances élevées.

Je suppose que tu aimes

Origine blog.csdn.net/qq_39939541/article/details/132308141
conseillé
Classement