Réflexion Java
La réflexion Java est une fonctionnalité puissante qui permet aux programmes d'interroger, d'accéder et de modifier des informations sur les classes, les interfaces, les champs et les méthodes à l'exécution. La réflexion offre la capacité de manipuler dynamiquement des classes, ce qui est largement utilisé dans de nombreux frameworks et bibliothèques, comme l'injection de dépendances dans le framework Spring.
API de réflexion
L'API de réflexion de Java fournit une série de classes et d'interfaces pour manipuler des objets Class. Les principales classes incluent :
java.lang.Class: Représente un objet Class. Fournit des méthodes pour obtenir les champs, les méthodes, les constructeurs, etc. de la classe.java.lang.reflect.Field: Représente les champs (attributs) d'une classe. Fournit la possibilité d'accéder aux champs et de les modifier.java.lang.reflect.Method: Représente les méthodes d'une classe. Fournit la possibilité d'invoquer des méthodes.java.lang.reflect.Constructor: Représente les constructeurs d'une classe. Fournit la possibilité de créer des objets.
Workflow
- Obtient
ClassObject: Tout d'abord, obtenez celui de la classe cibleClassobjet. - Obtenir des informations sur les membres: À travers l'
Classobjet, vous pouvez obtenir des informations sur les champs, les méthodes, les constructeurs, etc. de la classe. - Manipuler les membres: Grâce à l'API de réflexion, vous pouvez lire et modifier les valeurs des champs, invoquer des méthodes et créer des objets.
Voici les méthodes d'utilisation de base de la réflexion Java et leurs applications courantes.
1. Obtention de l'objet Class
Chaque classe a un objet Class associé dans la JVM. Vous pouvez obtenir l'objet Class des manières suivantes :
Via les littéraux de classe
Class<?> clazz = String.class;
Via une instance d’objet :
String str = "Hello"; Class<?> clazz = str.getClass();
Via la méthode Class.forName() :
Class<?> clazz = Class.forName("java.lang.String");
2. Création d’objets
Vous pouvez utiliser la réflexion pour créer dynamiquement des objets :
Class<?> clazz = Class.forName("java.lang.String");
Object obj = clazz.getDeclaredConstructor().newInstance();
3. Accès aux champs
Vous pouvez accéder aux champs d’une classe et les modifier via la réflexion :
Class<?> clazz = Person.class;
Field field = clazz.getDeclaredField("name");
field.setAccessible(true); // 如果字段是私有的,需要设置为可访问
Object value = field.get(personInstance); // 获取字段值
field.set(personInstance, "New Name"); // 设置字段值
4. Appel de méthodes
Vous pouvez appeler les méthodes d’une classe via la réflexion :
Class<?> clazz = Person.class;
Method method = clazz.getMethod("sayHello");
method.invoke(personInstance);
Method methodWithArgs = clazz.getMethod("greet", String.class);
methodWithArgs.invoke(personInstance, "World");
5. Obtention des constructeurs
Vous pouvez utiliser la réflexion pour obtenir et appeler des constructeurs :
Class<?> clazz = Person.class;
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("John", 30);
6. Obtention des interfaces et des classes parentes
Vous pouvez utiliser la réflexion pour obtenir les interfaces implémentées par la classe et sa classe parente :
Class<?> clazz = Person.class;
// 获取所有接口
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> i : interfaces) {
System.out.println("Interface: " + i.getName());
}
// 获取父类
Class<?> superClass = clazz.getSuperclass();
System.out.println("Superclass: " + superClass.getName());
L'exemple complet suivant montre comment utiliser la réflexion pour créer des objets, accéder aux champs et invoquer des méthodes :
Exemple
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// Obtenir l'objet Class
Class<?> clazz = Person.class;
// Créer un objet
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object person = constructor.newInstance("John", 30);
// Accéder aux champs
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
System.out.println("Nom : " + nameField.get(person));
// Modifier les champs
nameField.set(person, "Doe");
System.out.println("Nom mis à jour : " + nameField.get(person));
// Invoquer les méthodes
Method greetMethod = clazz.getMethod("greet", String.classe);
greetMethod.invoke(person, "Monde");
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void greet(String message) {
System.out.println(name + " dit : " + message);
}
}
Compilez et exécutez le code ci-dessus, le résultat de sortie est :
Name: John Updated Name: Doe Doe says: World
java.lang.reflect
java.lang.reflectC'est le package central du mécanisme de réflexion Java, fournissant des classes et des interfaces pour manipuler les classes et leurs membres (champs, méthodes, constructeurs, etc.). Grâce à ces API, les développeurs peuvent interroger et modifier dynamiquement la structure des classes à l'exécution.

Les suivantes sontjava.lang.reflectintroductions détaillées aux principales classes et interfaces du package :
1. ClassClasse
- Function: Représente un objet de classe, fournit des méthodes pour obtenir des informations sur la classe, telles que les champs, les méthodes, les constructeurs, etc.
- Méthodes principales:
getFields(): Récupère tous les champs publics.getDeclaredFields(): Récupère tous les champs déclarés, y compris les champs privés.getMethods(): Récupère toutes les méthodes publiques.getDeclaredMethods(): Récupère toutes les méthodes déclarées, y compris les méthodes privées.getConstructors(): Récupère tous les constructeurs publics.getDeclaredConstructors(): Récupère tous les constructeurs déclarés, y compris les constructeurs privés.getSuperclass(): Récupère la classe parente de la classe.getInterfaces(): Obtenir toutes les interfaces implémentées par la classe.
2. FieldClasse
- Fonction: Représente les champs (attributs) d'une classe, fournit des méthodes pour accéder aux valeurs des champs et les modifier.
- Méthodes principales:
get(Object obj): Obtenir la valeur du champ de l'objet spécifié.set(Object obj, Object value): Définir la valeur du champ de l'objet spécifié.getType(): Obtenir le type de données du champ.getModifiers(): Obtenir les modificateurs du champ (tels que public, private).
3. MethodClasse
- Fonction: Représente les méthodes d'une classe, fournit la capacité d'invoquer des méthodes.
- Méthodes principales:
invoke(Object obj, Object... args): Invoquer la méthode de l'objet spécifié.getReturnType(): Obtenir le type de retour de la méthode.getParameterTypes(): Obtenir les types des paramètres de la méthode.getModifiers(): Obtenir les modificateurs de la méthode (tels que public, private).
4. ConstructorClasse
- Fonction: Représente les constructeurs d'une classe, fournit la capacité de créer des objets.
- Méthodes principales:
newInstance(Object... initargs): Créer une nouvelle instance en utilisant les paramètres du constructeur spécifiés.getParameterTypes(): Obtenir les types des paramètres du constructeur.getModifiers(): Obtenir les modificateurs du constructeur (tels que public, private).
Exemple de code
Voici un exemple utilisant lejava.lang.reflectpaquet pour les opérations de réflexion :
Exemple
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// Obtenir l'objet Class
Class<?> clazz = Car.class;
// Créer un objet Car
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object car = constructor.newInstance("Toyota", 2020);
// Accéder aux champs et les modifier
Field modelField = clazz.getDeclaredField("model");
Field yearField = clazz.getDeclaredField("year");
// Rendre le champ accessible (si le champ est privé)
modelField.setAccessible(true);
yearField.setAccessible(true);
// Afficher la valeur d'origine du champ
System.out.println("Modèle d'origine : " + modelField.get(car));
System.out.println("Année d'origine : " + yearField.get(car));
// Modifier la valeur du champ
modelField.set(car, "Honda");
yearField.set(car, 2024);
// Afficher la valeur modifiée du champ
System.out.println("Modèle mis à jour : " + modelField.get(car));
System.out.println("Année mise à jour : " + yearField.get(car));
// Invoquer les méthodes
Method startMethod = clazz.getMethod("start");
startMethod.invoke(car);
}
}
class Car {
private String model;
private int year;
public Car(String model, int year) {
this.model = model;
this.year = year;
}
public void start() {
System.out.println("La " + model + " voiture de l'année " + year + " démarre.");
}
}
Compilez et exécutez le code ci-dessus, le résultat de sortie est :
Original Model: Toyota Original Year: 2020 Updated Model: Honda Updated Year: 2024 The Honda car of year 2024 is starting.Autres extensions