Maison  >  Article  >  Java  >  Qu’est-ce que la réflexion Java ? Introduction détaillée au mécanisme de réflexion Java

Qu’est-ce que la réflexion Java ? Introduction détaillée au mécanisme de réflexion Java

不言
不言original
2018-09-19 14:30:161965parcourir

Le contenu de cet article porte sur qu'est-ce que la réflexion Java ? L'introduction détaillée du mécanisme de réflexion Java a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer, j'espère qu'elle vous sera utile.

1. Concept

La réflexion Java (Reflection) signifie que lorsque le programme Java est en cours d'exécution, il peut charger une classe dont le nom est connu uniquement, obtenir la méthode de construction complète de la classe, et instancier l'objet, en donnant des valeurs définies pour les propriétés de l'objet ou en appelant des méthodes d'objet. Cette fonction d'obtention dynamique d'informations de classe et d'appel dynamique de méthodes d'objet au moment de l'exécution est appelée mécanisme de réflexion de Java.

2. Classe Class

La classe Class hérite de la classe Object et constitue l'entrée du mécanisme de réflexion Java. Elle encapsule les informations d'exécution d'une classe ou d'une interface et peut être obtenue en appelant. la méthode de la classe Class cette information. Comment comprendre cette classe Class ? Si une classe ordinaire est une collection de toutes les méthodes et attributs objets, alors cette classe Class peut être comprise comme une collection de toutes les classes ordinaires.

Voici plusieurs méthodes pour obtenir la classe Class :

public class TestClass {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1、 Class.forName();
        Class<?> aClass0 = Class.forName("java.lang.Object");
        // 2、类名.Class
        Class<Integer> aClass1 = Integer.class;
        // 3、包装类.TYPE —— 返回基本类型的 Class 引用,基本类型在虚拟机运行时就已经加载了它的Class
        Class<Integer> aClass2 = Integer.TYPE;
        // 4、对象名.getClass()
        String str = "Hello, World";
        Class<? extends String> aClass3 = str.getClass();
        // 5、Class类.getSuperClass() —— 获得父类的 Class 对象
        Class<?> aClass4 = aClass3.getSuperclass();

        System.out.println(aClass0.getName());
        System.out.println(aClass1.getName());
        System.out.println(aClass2.getName());
        System.out.println(aClass3.getName());
        System.out.println(aClass4.getName());
    }
}

3. Obtention des informations sur la classe

Afin de tester le mécanisme de réflexion de Java, j'ai créé un. nouvelle paire de classe père et fils, qui couvre quatre attributs d'encapsulation pour tester autant que possible l'acquisition de plusieurs types d'informations :

Vehicle.java

vpublic class Vehicle {
    private String color;
    protected Integer seat;
    int year;
    public Date createdOn;
    private String getColor() {
        return color;
    }
    protected Integer getSeat() {
        return seat;
    }
    int getYear() {
        return year;
    }
    public Date getCreatedOn() {
        return createdOn;
    }
}

Voiture. .java

public class Car extends Vehicle {
    private String brand;
    protected Integer a;
    int b;
    public Date updatedOn;
    public Car(){}
    private Car(String brand, Integer a, int b, Date updatedOn) {
        this.brand = brand;
        this.a = a;
        this.b = b;
        this.updatedOn = updatedOn;
    }
    private String getBrand() {
        return brand;
    }
    protected Integer getA() {
        return a;
    }
    int getB() {
        return b;
    }
    public Date getUpdatedOn() {
        return updatedOn;
    }
}

1. Get méthodes

La classe Class obtient principalement des méthodes des deux manières suivantes :

Method[] getMethods() renvoie la classe ou l'interface Toutes les méthodes publiques accessibles (y compris les méthodes publiques héritées).

Method[] getDeclaredMethods() Renvoie toutes les méthodes de cette classe ou interface (à l'exclusion des méthodes héritées).

public class TestMethod {
    public static void main(String[] args) {
        Class<Car> carClass = Car.class;
        Method[] methods = carClass.getMethods();
        Method[] declaredMethods = carClass.getDeclaredMethods();

        for (Method method : methods) {
        //for (Method method : declaredMethods) {
            System.out.println("方法名:" + method.getName());
            System.out.println("该方法所在的类或接口:" + method.getDeclaringClass());
            System.out.println("该方法的参数列表:" + method.getParameterTypes());
            System.out.println("该方法的异常列表:" + method.getExceptionTypes());
            System.out.println("该方法的返回值类型:" + method.getReturnType());
        }
    }
}

2. Obtenir les attributs

La classe Class obtient principalement les attributs des deux manières suivantes :

Field[] getFields() : Stores toutes les propriétés publiques accessibles de la classe ou de l'interface (y compris les propriétés publiques héritées).

Field[] getDeclaredFields() : stocke toutes les propriétés de la classe ou de l'interface (à l'exclusion des propriétés héritées).

public class TestField {
    public static void main(String[] args) {
        Class<Car> carClass = Car.class;
        Field[] fields = carClass.getFields();
        Field[] declaredFields = carClass.getDeclaredFields();
        //for (Field field : fields) {
        for (Field field : declaredFields) {
            System.out.println("属性名称是:" + field.getName());
            System.out.println("该属性所在的类或接口是:" + field.getDeclaringClass());
            System.out.println("该属性的类型是:" + field.getType());
            // field.getModifiers() 以整数形式返回由此 Field 对象表示的属性的 Java 访问权限修饰符
            System.out.println("该属性的修饰符是:" + Modifier.toString(field.getModifiers()));
        }
    }
}

3. Obtenir le constructeur

La classe Class obtient principalement la méthode constructeur des deux manières suivantes :

Constructeur495955736db7968c4332ac994a743276[] getDeclaredConstructors() : renvoie tous les constructeurs publics de cette classe ou interface

public class TestConstructor {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<Car> carClass = Car.class;
        Constructor<?>[] constructors = carClass.getConstructors();
        Constructor<?>[] declaredConstructors = carClass.getDeclaredConstructors();
        Constructor<Car> carConstructor = carClass.getDeclaredConstructor(String.class, Integer.class, Integer.TYPE, Date.class);
        //for (Constructor constructor : declaredConstructors) {
        for (Constructor constructor : constructors) {
            System.out.println("该构造器的名称是:" + constructor.getName());
            System.out.println("该构造器所在的类或接口是:" + constructor.getDeclaringClass());
            //返回构造方法的参数类型
            constructor.getParameterTypes();
        }
    }
}

4. Appel dynamique

Jusqu'à présent, nous avons obtenu les informations détaillées sur les attributs, méthodes et constructeurs de classe correspondants via les méthodes de la classe Class. Nous utiliserons ensuite ces informations pour créer dynamiquement des objets, modifier des propriétés et appeler dynamiquement des méthodes.

public class Test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<Car> carClass = Car.class;
        // 1、实例化对象
        // 调用 Class 类的newInstance();要求对应类必须有无参构造函数,相当于 Car car = new Car()
        Car car = carClass.newInstance();
        // 调用构造器的newInstance(Object ... initargs);
        Constructor<Car> declaredConstructor = carClass.getDeclaredConstructor(String.class, Integer.class, Integer.TYPE, Date.class);
        // 取消访问权限控制,即使是 private 权限也可以访问
        declaredConstructor.setAccessible(true);
        Car car1 = declaredConstructor.newInstance("brand", 21, 21, new Date());
        System.out.println(car1.getUpdatedOn());

        // 2、修改属性
        Field brand = carClass.getDeclaredField("brand");
        brand.setAccessible(true);
        System.out.println("取消访问权限控制后的值:" + brand.get(car1));
        brand.set(car1, "dnarb");
        System.out.println("修改属性后的值是:" + brand.get(car1));

        // 3、调用方法
        Method getBrand = carClass.getDeclaredMethod("getBrand");
        getBrand.setAccessible(true);
        System.out.println("调用反射方法得到的值是:" + getBrand.invoke(car1));
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn