Clases relacionadas con la reflexión de Java y principios subyacentes

1. Clases principales de reflexión de Java:

1. Clase:

Representa una instancia de una clase Java y se puede utilizar para obtener información de la clase, como el nombre de la clase, la clase principal, la interfaz, los campos, los métodos, etc. Puede usar el método Class.forName() para obtener un objeto Class según el nombre de la clase, o usar el método getClass() del objeto para obtener un objeto Class.

Aquí hay un código de muestra simple que demuestra cómo usar la reflexión para obtener información de clase:

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 {
    
    
    // 接口
}

Resultado de salida:

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. Clase de constructor:

Representa el método constructor de una clase, que se puede utilizar para crear instancias de la clase. Puede utilizar el método getConstructor() o el método getDeclaredConstructor() de la clase Class para obtener el objeto Constructor y luego utilizar el método newInstance() para crear una instancia.

A continuación se muestra un ejemplo sencillo que demuestra cómo utilizar el método constructor para crear una instancia de una clase:

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

En el ejemplo anterior, primero usamos MyClass.class.getConstructor(String.class) para obtener el objeto constructor de la clase MyClass, y el constructor acepta un parámetro de tipo String. Luego, usamos constructor.newInstance("John") para crear una instancia, y el parámetro "John" se pasará como parámetro del constructor. Finalmente, llamamos al método de instancia printName() para imprimir el nombre de la instancia.

3. Clase de campo:

Representa un campo de una clase que se puede utilizar para obtener y establecer el valor del campo. Puede usar el método getField() o getDeclaredField() de la clase Class para obtener el objeto Field, y luego usar el método get() para obtener el valor del campo, o usar el método set() para establecer el valor del campo.

A continuación se muestra un ejemplo sencillo que demuestra cómo utilizar campos para obtener y establecer el valor de un campo:

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

En el ejemplo anterior, creamos una instancia de la clase MyClass y usamos el método getField() para obtener el objeto Field del campo de nombre, y usamos el método getDeclaredField() para obtener el objeto Field del campo de edad. El método getDeclaredField() puede obtener campos privados, pero los campos privados son inaccesibles de forma predeterminada, por lo que debemos llamar a setAccessible(true) para configurar los campos privados para que sean accesibles.

Luego, usamos el método get() para obtener los valores del campo de nombre y el campo de edad respectivamente, y usamos el método set() para establecer el valor del campo de nombre en "Alice" y el valor del campo de edad. a 30. Finalmente, llamamos al método printInfo() para imprimir el valor del campo y verificar si el valor del campo ha sido modificado. Tenga en cuenta que se requiere conversión de tipo para obtener y establecer el valor del campo.

4. Clase de método:

Representa un método de clase que se puede utilizar para llamar a métodos. Puede utilizar el método getMethod() o el método getDeclaredMethod() de la clase Class para obtener el objeto Method y luego utilizar el método invoke() para llamar al método.

Aquí hay un código de ejemplo que usa la reflexión para llamar a un método de una clase:

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

Resultado de salida:

调用了myMethod方法

En el código anterior, primero obtenemos el objeto Clase de la clase MyClass a través de MyClass.class. Luego use el método getMethod() para pasar el nombre del método para obtener el objeto Método del método myMethod.

A continuación, creamos una instancia de la clase MyClass myObj.

Finalmente, usamos el método invoke() para llamar al método myMethod, pasando myObj como el llamador del método. Esto llama con éxito al método myMethod.

Cabe señalar que si el método myMethod es un método privado o un método heredado de la clase principal, debe utilizar el método getDeclaredMethod() para obtener el objeto Método. Y antes de llamar al método invoke(), debes llamar a setAccessible(true) para configurar la accesibilidad del método.

2. El principio subyacente de la reflexión

  1. Durante la ejecución de un programa Java, primero es necesario compilar el código fuente para generar el archivo de código de bytes correspondiente (archivo .class). Luego, la JVM cargará estos archivos de código de bytes y creará la información de clase correspondiente en el área de métodos, incluido el nombre de la clase, la clase principal, la interfaz, los campos, los métodos, etc.

  2. La reflexión consiste en lograr operaciones dinámicas en clases obteniendo esta información de clase. Al obtener el objeto Clase de una clase, puede obtener el nombre, la clase principal, la interfaz y otra información de la clase.
    A través de los métodos del objeto Clase, puede obtener el constructor, los campos, los métodos y otra información de los miembros de la clase, y puede crear objetos dinámicamente, llamar a métodos, acceder a campos, etc.

  3. El mecanismo de reflexión permite que el programa obtenga y opere dinámicamente información de clases en tiempo de ejecución sin determinar la estructura de clases en tiempo de compilación. Esto proporciona comodidad para el desarrollo de marcos, proxy dinámico, lectura de archivos de configuración, etc. Sin embargo, cabe señalar que el uso de la reflexión puede provocar ciertas pérdidas de rendimiento, por lo que debe utilizarse con precaución en escenarios con requisitos de alto rendimiento.

Supongo que te gusta

Origin blog.csdn.net/qq_39939541/article/details/132308141
Recomendado
Clasificación