Java-Reflexion
Java-Reflexion ist eine leistungsstarke Funktion, die es Programmen ermöglicht, Informationen über Klassen, Schnittstellen, Felder und Methoden zur Laufzeit abzufragen, darauf zuzugreifen und sie zu ändern. Die Reflexion bietet die Möglichkeit, Klassen dynamisch zu manipulieren, was in vielen Frameworks und Bibliotheken weit verbreitet ist, z. B. bei der Dependency Injection im Spring-Framework.
Reflexions-API
Die Reflexions-API von Java bietet eine Reihe von Klassen und Schnittstellen zur Manipulation von Class-Objekten. Zu den wichtigsten Klassen gehören:
java.lang.Class: Repräsentiert ein Class-Objekt. Bietet Methoden zum Abrufen der Felder, Methoden, Konstruktoren usw. der Klasse.java.lang.reflect.Field: Repräsentiert die Felder (Attribute) einer Klasse. Bietet die Möglichkeit, auf Felder zuzugreifen und sie zu ändern.java.lang.reflect.Method: Repräsentiert die Methoden einer Klasse. Bietet die Möglichkeit, Methoden aufzurufen.java.lang.reflect.Constructor: Repräsentiert die Konstruktoren einer Klasse. Bietet die Möglichkeit, Objekte zu erstellen.
Workflow
- Abrufen
ClassObject: Zuerst das Class-Objekt der Zielklasse abrufenClassObjekt. - Member-Informationen abrufen: Über das
ClassObjekt, können Sie Informationen über die Felder, Methoden, Konstruktoren usw. der Klasse abrufen. - Member manipulieren: Über die Reflection-API können Sie Feldwerte lesen und ändern, Methoden aufrufen und Objekte erstellen.
Im Folgenden finden Sie die grundlegenden Verwendungsmethoden der Java-Reflection und ihre gängigen Anwendungen.
1. Abrufen des Class-Objekts
Jede Klasse hat ein zugehöriges Class-Objekt in der JVM. Sie können das Class-Objekt auf folgende Weise abrufen:
Über Klassenliterale
Class<?> clazz = String.class;
Über eine Objektinstanz:
String str = "Hello"; Class<?> clazz = str.getClass();
Über die Methode Class.forName():
Class<?> clazz = Class.forName("java.lang.String");
2. Objekte erstellen
Sie können Reflection verwenden, um Objekte dynamisch zu erstellen:
Class<?> clazz = Class.forName("java.lang.String");
Object obj = clazz.getDeclaredConstructor().newInstance();
3. Zugriff auf Felder
Sie können über Reflection auf Klassenfelder zugreifen und sie ändern:
Class<?> clazz = Person.class;
Field field = clazz.getDeclaredField("name");
field.setAccessible(true); // 如果字段是私有的,需要设置为可访问
Object value = field.get(personInstance); // 获取字段值
field.set(personInstance, "New Name"); // 设置字段值
4. Aufrufen von Methoden
Sie können Klassenmethoden über Reflection aufrufen:
Class<?> clazz = Person.class;
Method method = clazz.getMethod("sayHello");
method.invoke(personInstance);
Method methodWithArgs = clazz.getMethod("greet", String.class);
methodWithArgs.invoke(personInstance, "World");
5. Konstruktoren abrufen
Sie können Reflection verwenden, um Konstruktoren abzurufen und aufzurufen:
Class<?> clazz = Person.class;
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("John", 30);
6. Schnittstellen und Elternklassen abrufen
Sie können Reflection verwenden, um die von der Klasse implementierten Schnittstellen und ihre Elternklasse abzurufen:
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());
Das folgende ist ein vollständiges Beispiel, das zeigt, wie man Reflection verwendet, um Objekte zu erstellen, auf Felder zuzugreifen und Methoden aufzurufen:
Beispiel
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// Das Class-Objekt abrufen
Class<?> clazz = Person.class;
// Ein Objekt erstellen
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object person = constructor.newInstance("John", 30);
// Auf Felder zugreifen
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
System.out.println("Name: " + nameField.get(person));
// Felder ändern
nameField.set(person, "Doe");
System.out.println("Aktualisierter Name: " + nameField.get(person));
// Methoden aufrufen
Method greetMethod = clazz.getMethod("greet", String.class);
greetMethod.invoke(person, "Welt");
}
}
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 + " sagt: " + message);
}
}
Kompilieren und führen Sie den obigen Code aus, das Ausgabeergebnis ist:
Name: John Updated Name: Doe Doe says: World
java.lang.reflect
java.lang.reflectEs ist das Kernpaket des Java-Reflection-Mechanismus und stellt Klassen und Schnittstellen für die Manipulation von Klassen und deren Mitgliedern (Felder, Methoden, Konstruktoren usw.) bereit. Über diese APIs können Entwickler die Struktur von Klassen zur Laufzeit dynamisch abfragen und ändern.

Die folgenden sindjava.lang.reflectausführliche Einführungen zu den Hauptklassen und Schnittstellen im Paket:
1. ClassKlasse
- Funktion: Repräsentiert ein Klassenobjekt und bietet Methoden zum Abrufen von Klasseninformationen, wie Felder, Methoden, Konstruktoren usw.
- Hauptmethoden:
getFields(): Alle öffentlichen Felder abrufen.getDeclaredFields(): Alle deklarierten Felder abrufen, einschließlich privater Felder.getMethods(): Alle öffentlichen Methoden abrufen.getDeclaredMethods(): Alle deklarierten Methoden abrufen, einschließlich privater Methoden.getConstructors(): Alle öffentlichen Konstruktoren abrufen.getDeclaredConstructors(): Alle deklarierten Konstruktoren abrufen, einschließlich privater Konstruktoren.getSuperclass(): Die Elternklasse der Klasse abrufen.getInterfaces(): Ruft alle von der Klasse implementierten Schnittstellen ab.
2. FieldKlasse
- Function: Stellt die Felder (Attribute) einer Klasse dar, bietet Methoden, um auf Feldwerte zuzugreifen und sie zu ändern.
- Hauptmethoden:
get(Object obj): Ruft den Feldwert des angegebenen Objekts ab.set(Object obj, Object value): Legt den Feldwert des angegebenen Objekts fest.getType(): Ruft den Datentyp des Felds ab.getModifiers(): Ruft die Modifikatoren des Felds ab (wie public, private).
3. MethodKlasse
- Function: Stellt die Methoden einer Klasse dar, bietet die Möglichkeit, Methoden aufzurufen.
- Hauptmethoden:
invoke(Object obj, Object... args): Ruft die Methode des angegebenen Objekts auf.getReturnType(): Ruft den Rückgabetyp der Methode ab.getParameterTypes(): Ruft die Parametertypen der Methode ab.getModifiers(): Ruft die Modifikatoren der Methode ab (wie public, private).
4. ConstructorKlasse
- Function: Stellt die Konstruktoren einer Klasse dar, bietet die Möglichkeit, Objekte zu erstellen.
- Hauptmethoden:
newInstance(Object... initargs): Erzeuge eine neue Instanz mit den angegebenen Konstruktorparametern.getParameterTypes(): Ermittle die Parametertypen des Konstruktors.getModifiers(): Ermittle die Modifikatoren des Konstruktors (wie public, private).
Beispielcode
Das Folgende ist ein Beispiel unter Verwendung desjava.lang.reflectPakets für Reflection-Operationen:
Beispiel
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// Das Class-Objekt abrufen
Class<?> clazz = Car.class;
// Ein Car-Objekt erstellen
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object car = constructor.newInstance("Toyota", 2020);
// Auf Felder zugreifen und sie ändern
Field modelField = clazz.getDeclaredField("model");
Field yearField = clazz.getDeclaredField("year");
// Das Feld als zugänglich festlegen (falls das Feld private ist)
modelField.setAccessible(true);
yearField.setAccessible(true);
// Ursprünglichen Feldwert ausgeben
System.out.println("Ursprüngliches Modell: " + modelField.get(car));
System.out.println("Ursprüngliches Jahr: " + yearField.get(car));
// Feldwert ändern
modelField.set(car, "Honda");
yearField.set(car, 2024);
// Geänderten Feldwert ausgeben
System.out.println("Aktualisiertes Modell: " + modelField.get(car));
System.out.println("Aktualisiertes Jahr: " + yearField.get(car));
// Methoden aufrufen
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("Das " + model + " Auto aus dem Jahr " + year + " startet.");
}
}
Kompilieren und führen Sie den obigen Code aus, das Ausgabeergebnis ist:
Original Model: Toyota Original Year: 2020 Updated Model: Honda Updated Year: 2024 The Honda car of year 2024 is starting.Andere Erweiterungen