[Java] Java-Lernen => [Reflexion]

Einführung

Wenn wir eine Klasse verwenden, müssen wir unter normalen Umständen wissen, um welche Klasse es sich handelt, wofür sie verwendet wird, und wir können einen Verweis darauf erhalten. Daher instanziieren wir diese Klasse direkt und verwenden dann dieses Klassenobjekt für den Betrieb.

Reflexion ist 不知道我要初始化的类对象am Anfang natürlich nichts 无法使用 new 关键字来创建对象. Zu diesem Zeitpunkt verwenden wir den von JDK bereitgestellten 反射 API Reflexionsaufruf . 反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。ist der Schlüssel dazu, dass Java als dynamische Sprache betrachtet wird.

Der Java-Reflexionsmechanismus bietet hauptsächlich die folgenden Funktionen:

Konstruieren Sie ein Objekt einer beliebigen Klasse zur Laufzeit.
Erhalten oder ändern Sie Mitgliedsvariablen und Methoden einer beliebigen Klasse
zur Laufzeit. Rufen Sie eine beliebige Methode (Attribut) eines Objekts zur Laufzeit auf

Klasse

反射始于Class, Klasse ist eine Klasse, 封装了当前对象所对应的类的信息. Eine Klasse verfügt über Attribute, Methoden, Konstruktoren usw. Es gibt beispielsweise eine Person-Klasse, eine Order-Klasse und eine Book-Klasse. Dies sind alles verschiedene Klassen. Jetzt benötigen wir eine Klasse, um die Klasse zu beschreiben. Dies ist die Klasse sollte Es gibt Klassennamen, Eigenschaften, Methoden, Konstruktoren usw. Klasse ist eine Klasse, die zur Beschreibung einer Klasse verwendet wird.

Die Class-Klasse ist das Ergebnis der Betrachtung eines Objekts im Spiegel. Das Objekt kann sehen, welche Eigenschaften, Methoden, Konstruktoren, welche Schnittstellen es implementiert hat usw. Für jede Klasse reserviert die JRE ein unveränderliches Objekt vom Typ Class. Ein Class-Objekt enthält Informationen über eine bestimmte Klasse.

Objekte können nur vom Systemobjekt erstellt werden 一个类(而不是一个对象)在 JVM 中只会有一个Class实例.

Holen Sie sich das Class-Objekt

Drei Möglichkeiten, das Klassenobjekt abzurufen
1. 通过类名获取 类名.class
2. 通过对象获取 对象名.getClass()
3. 通过全类名获取 Class.forName(全类名) classLoader.loadClass(全类名)

Verwenden Sie die statische Methode forName der Class-Klasse

public static Class<?> forName(String className)

Rufen Sie die Klasse eines Objekts direkt ab

Class<?> klass = int.class;
Class<?> classInt = Integer.TYPE;

Rufen Sie die Methode getClass() eines Objekts auf

StringBuilder str = new StringBuilder("123");
Class<?> klass = str.getClass();

Bestimmen Sie, ob es sich um eine Instanz einer Klasse handelt

Im Allgemeinen verwenden wir instanceofSchlüsselwörter, um zu beurteilen, ob es sich um eine Instanz einer bestimmten Klasse handelt. Gleichzeitig können wir auch isInstance() die Methode des Klassenobjekts in der Reflektion verwenden, um zu bestimmen, ob es sich um eine Instanz einer bestimmten Klasse handelt, bei der es sich um eine native Methode handelt:

public native boolean isInstance(Object obj);

Bestimmen Sie, ob es sich um einen Typ einer Klasse handelt

public boolean isAssignableFrom(Class<?> cls)

Instanz erstellen

Es gibt zwei Hauptmethoden, Objekte durch Reflexion zu erzeugen

Verwenden Sie die Methode newInstance() des Class-Objekts, um eine Instanz der Klasse zu erstellen, die dem Class-Objekt entspricht.

Class<?> c = String.class;
Object str = c.newInstance();

Rufen Sie zunächst das angegebene Konstruktorobjekt über das Klassenobjekt ab und rufen Sie dann die newInstance()-Methode des Konstruktorobjekts auf, um eine Instanz zu erstellen. Diese Methode erstellt eine Instanz der Klasse mit dem angegebenen Konstruktor.

//获取String所对应的Class对象
Class<?> c = String.class;
//获取String类带一个String参数的构造器
Constructor constructor = c.getConstructor(String.class);
//根据构造器创建实例
Object obj = constructor.newInstance("23333");
System.out.println(obj);

Konstruktorinformationen abrufen

Holen Sie sich die Konstruktormethode

Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的public构造函数(包括父类)
Constructor[] getConstructors() -- 获得类的所有公共构造函数
Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(包括私有)
Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)

Die Verwendung des Abrufens eines Klassenkonstruktors ähnelt der oben beschriebenen Verwendung der Methoden zum Abrufen. Rufen Sie eine Instanz der Constructor-Klasse hauptsächlich über die getConstructor-Methode der Class-Klasse ab, und die Constructor-Klasse verfügt über eine newInstance-Methode zum Erstellen einer Objektinstanz

public T newInstance(Object ... initargs)

Rufen Sie die Informationen zur Mitgliedsvariablen (Feld) der Klasse ab

Methode zum Abrufen von Feldinformationen

Field getField(String name) -- 获得命名的公共字段
Field[] getFields() -- 获得类的所有公共字段
Field getDeclaredField(String name) -- 获得类声明的命名的字段
Field[] getDeclaredFields() -- 获得类声明的所有字段

Aufrufmethode

Möglichkeiten, Methodeninformationen zu erhalten

Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法
Method[] getMethods() -- 获得类的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法
Method[] getDeclaredMethods() -- 获得类声明的所有方法

Wenn wir eine Methode von einer Klasse erhalten, können wir diese Methode mit der Methode invoke() aufrufen. Der Prototyp der Aufrufmethode ist

public Object invoke(Object obj, Object... args)

Erstellen Sie ein Array mithilfe von Reflektion

Array ist ein spezieller Typ in Java. Er kann einer Objektreferenz zugewiesen werden, wobei die Array-Klasse die
Klasse java.lang.reflect.Array ist. Wir erstellen ein Array-Objekt über Array.newInstance() und sein Prototyp ist:

public static Object newInstance(Class<?> componentType, int length);

Reflexion, um den generischen Realtyp zu erhalten

Wenn wir über eine generische Klasse nachdenken, benötigen wir den echten Datentyp im Generikum, um Vorgänge wie die JSON-Deserialisierung abzuschließen. Zu diesem Zeitpunkt muss es über das Typsystem abgeschlossen werden. Die Typschnittstelle enthält eine Implementierungsklasse (Class) und vier Implementierungsschnittstellen:

TypeVariable
Generische Typvariable. Informationen wie Ober- und Untergrenzen können allgemeiner Natur sein;

ParameterizedType
Für bestimmte generische Typen kann der generische Signaturtyp (generischer realer Typ) in den Metadaten abgerufen werden

GenericArrayType
Wenn der zu beschreibende Typ ein Array generischer Klassen ist, z. B. List[], Map[], wird diese Schnittstelle als Typ implementiert.

WildcardType
Wildcard-Generika, um Informationen zu Ober- und Untergrenzen zu erhalten;

Ich denke du magst

Origin blog.csdn.net/qq_43358469/article/details/131310057
Empfohlen
Rangfolge