(1). Schnittstellentypen im Zusammenhang mit Reflexion + Generika
java.lang.reflect.Type: Gemeinsame übergeordnete Schnittstelle für alle Typen in der Java-Sprache
java.lang.reflect.ParameterizedType
java.lang.reflect.GenericArrayType
java.lang.reflect.WildcardType
1. Geben Sie direkte Unterschnittstelle ein
Vier Arten von Schnittstellen: ParameterizedType, GenericArrayType, TypeVariable und WildcardType
ParameterizedType: stellt einen parametrisierten Typ dar, z. B. Collection
GenericArrayType: stellt einen Array-Typ dar, dessen Elementtyp ein parametrisierter Typ oder eine Typvariable ist
TypeVariable: ist die gemeinsame übergeordnete Schnittstelle für verschiedene Arten von Variablen
WildcardType: Stellt einen Ausdruck vom Typ Wildcard dar, z. B. ?, ? erweitert Number, ? super Integer [Wildcard ist ein Wort: es ist „Wildcard“]
2. Typ implementiert direkt Unterklassen: Klasse class
3. java.lang.reflect.Type-Schnittstelle
Alle Typentypen beziehen sich auf: Rohtypen (Rohtypen) [entsprechend Klasse], parametrisierte Typen (parametrisierte Typen) [entsprechend ParameterizedType], Array-Typen (Array-Typen) [entsprechend GenericArrayType], Typvariablen (Typvariablen) [ entsprechend TypeVariable], grundlegende Datentypen (primitivetypes) [entspricht immer noch Class]
4. java.lang.reflect.ParameterizedType-Schnittstelle
Die Bedeutung des Schnittstellentyps ParameterizedType
Stellt einen parametrisierten Typ dar. Beispiel: ein parametrisierter Typ wie Map
Rufen Sie den tatsächlichen Typ im parametrisierten Typ <> ab
Quellcode-Anweisung: Type[] getActualTypeArguments();
[Hinweis] Unabhängig davon, wie viele Ebenen der <>-Verschachtelung es in <> gibt, entfernt diese Methode nur das äußerste <> und der verbleibende Inhalt wird als Rückgabewert dieser Methode verwendet.
öffentliche statische E-MethodeIV(
ArrayList> al1,
ArrayList al2,
ArrayList al3,
ArrayListextends Number> al4,
ArrayList al5){}
Dann ist jeder seiner Parameter im Allgemeinen vom parametrischen Typ.
{1}. Für ArrayList> ist nach der Rückkehr über getActualTypeArguments() nach dem Entfernen des äußersten <> der verbleibende Typ ArrayList. Daher ist der Rückgabetyp für diesen Parameter ParameterizedType.
{2} Für ArrayList ist nach der Rückkehr über getActualTypeArguments() nach dem Entfernen des äußersten <> der verbleibende Typ E. Daher ist der Rückgabetyp für diesen Parameter TypeVariable.
{3}. Für ArrayList ist nach der Rückkehr über getActualTypeArguments() nach dem Entfernen des äußersten <> der verbleibende Typ String. Daher ist der Rückgabetyp für diesen Parameter Class.
{4}. Für ArrayListextends Number> ist nach der Rückkehr über getActualTypeArguments() nach dem Entfernen des äußersten <> der verbleibende Typ? Daher ist der Rückgabetyp für diesen Parameter WildcardType.
{5}. Für ArrayList ist nach der Rückkehr über getActualTypeArguments() nach dem Entfernen des äußersten <> der verbleibende Typ E[]. Daher ist der Rückgabetyp für diesen Parameter GenericArrayType.
Daher ist es möglich, tatsächliche Parameter verschiedener Typen zu erhalten. Aus Gründen der Vereinheitlichung wird daher das Array Type[] der direkten übergeordneten Klasse für den Empfang verwendet.
4. java.lang.reflect.GenericArrayType-Schnittstelle
Die Bedeutung des Schnittstellentyps GenericArrayType
Stellt einen generischen Array-Typ dar. Zum Beispiel: void method(ArrayList[] al){…}
[Hinweis] <> darf bei der Initialisierung des Arrays nicht angezeigt werden, dh <> kann nicht nach dem neuen Array angezeigt werden, da Javac sonst nicht übergeben wird. Aber als Referenzvariable oder Parameter einer Methode ist es völlig in Ordnung.
Rufen Sie den Typ der Elemente in einem generischen Array ab
Quellcode-Deklaration: Typ getGenericComponentType();
[Hinweis] Unabhängig davon, wie viele [] von links nach rechts nebeneinander angeordnet sind, entfernt diese Methode nur das ganz rechte [] und der verbleibende Inhalt wird als Rückgabewert dieser Methode verwendet.
Warum ist der Rückgabewerttyp Typ?
öffentliche statische E-MethodeV(String[] p1,E[] p2,ArrayList[] p3,E[][] p4){}{1}. Für String[] ist nach der Rückkehr über getComponentType() nach dem Entfernen des ganz rechten [] der verbleibende Typ String. Daher ist der Rückgabetyp für diesen Parameter Class
{2}. Für E[] ist nach der Rückkehr über getComponentType() nach dem Entfernen des ganz rechten [] der verbleibende Typ E. Daher ist der Rückgabetyp für diesen Parameter TypeVariable
{3}. Für ArrayList[] ist nach der Rückkehr über getComponentType() nach dem Entfernen des ganz rechten [] der verbleibende Typ ArrayList. Daher ist der Rückgabetyp für diesen Parameter ParameterizedType
{4}. Für E[][] ist nach der Rückkehr über getComponentType() nach dem Entfernen des ganz rechten [] der verbleibende Typ E[]. Daher ist der Rückgabetyp für diesen Parameter GenericArrayType
5. java.lang.reflect.GenericArrayType-Schnittstelle
Die Bedeutung des TypeVariable-Schnittstellentyps
Stellt Typparameter dar oder wird auch Typvariablen genannt. Beispiel: E in void method(E e){} ist die Typvariable
Ruft den Typ der generisch qualifizierten Obergrenze einer Typvariablen ab
Quellcode-Anweisung: Type[] getActualTypeArguments();
[Hinweis] Dies ist nur die Obergrenze. Der Grund dafür ist, dass Typvariablen Extends nur verwenden können, um (mehrere) Grenzen einzuschränken, wenn sie definiert sind. Super kann nicht verwendet werden, da sonst die Kompilierung nicht erfolgreich ist. Gleichzeitig gibt Extens die Obergrenze von Typvariablen an.
Warum ist der Rückgabetyp ein Array? Da Typvariablen durch & mit mehreren Obergrenzen qualifiziert werden können, gibt es mehrere Obergrenzen, sodass der Rückgabewerttyp der Array-Typ [] ist.
Zum Beispiel die folgende Methode:
public static erweitert Map& Cloneable&Serializable> E methodVI(E e){…}Die erste obere Grenze von E ist Map, ein ParameterizedType-Typ
Die zweite obere Grenze von E ist Cloneable, also vom Typ Klasse
Daher ist zur Vereinheitlichung der Elementtyp des Arrays der Rückgabewerte Type
6. java.lang.reflect.WildcardType-Schnittstelle
Die Bedeutung des WildcardType-Schnittstellentyps
Ein Ausdruck, der einen Platzhaltertyp darstellt.
Beispielsweise erweitert ? Number in void printColl(ArrayListal);
[Hinweis] Gemäß den Kommentaren der obigen API: Derzeit akzeptieren Platzhalterausdrücke nur eine Obergrenze oder Untergrenze, was sich von mehreren Obergrenzen unterscheidet, die beim Definieren von Typvariablen angegeben werden können. Die API sagte jedoch, dass der Rückgabewerttyp hier zur Aufrechterhaltung der Skalierbarkeit in Form eines Arrays geschrieben wird. Tatsächlich beträgt die Größe des jetzt zurückgegebenen Arrays 1
Ruft den Typ der generisch qualifizierten Obergrenze eines Platzhalterausdrucksobjekts ab
Quellcode-Anweisung: Type[] getUpperBounds();
[Hinweis] Wie oben erwähnt, beträgt die Größe des in dieser Phase zurückgegebenen Arrays in Type[] 1. Geschrieben als Type[ ] ist eine Erweiterung für die Sprachaktualisierung.
Zum Beispiel die folgende Methode:
{1}. public static voidprintColl(ArrayListextends ArrayList> al){}
Der Platzhalterausdruck lautet: „extensArrayList“, sodass auf „extens“ die obere Grenze von „?“ folgt und diese obere Grenze der Typ „ParameterizedType“ ist.
{2}. public static voidprintColl(ArrayListextends E> al){}
Der Platzhalterausdruck lautet: „extends E“, sodass auf „extens“ die Obergrenze von „?“ folgt und diese Obergrenze der Typ „TypeVariable“ ist
{3}.public static voidprintColl(ArrayListextends E[]> al){}
Der Platzhalterausdruck lautet: „extends E[], sodass auf „extens“ die obere Grenze von „?“ folgt und diese obere Grenze vom Typ „GenericArrayType“ ist
{4}.public static voidprintColl(ArrayListextends Number> al){}
Der Platzhalterausdruck lautet: „extends Number“, sodass auf „extens“ die Obergrenze von „?“ folgt und diese Obergrenze der Klassentyp ist
Schließlich wird Type als Elementtyp des Arrays vereinheitlicht.
7. Der Ursprung des Typs und seiner Unterschnittstellen
1. Typen vor dem Aufkommen der Generika
Wenn es keine Generika gibt, gibt es nur sogenannte primitive Typen. Zu diesem Zeitpunkt werden alle primitiven Typen durch die Bytecode-Dateiklasse Class-Klasse abstrahiert. Ein konkretes Objekt der Class-Klasse repräsentiert einen angegebenen primitiven Typ.
2. Typen nach dem Aufkommen der Generika
Nach dem Aufkommen von Generika wurden die Datentypen erweitert. Von nur primitiven Typen wurden parametrisierte Typen, Typvariablentypen, generisch qualifizierte parametrisierte Typen (einschließlich Platzhalter + Platzhalter qualifizierter Ausdrücke) und generische Array-Typen erweitert.
3. Der Grund, warum Typen, die sich auf Generika beziehen, nicht mit Originaltypen in der Klasse vereint werden können
[1]. [Ursache der generischen Löschung]
Ursprünglich sollten die neu generierten Typen + Grundtypen in ihren jeweiligen Bytecode-Dateitypobjekten vereinheitlicht werden. Aber da Generika ursprünglich kein Bestandteil von Java waren. Wenn wirklich Generika hinzugefügt werden, ist eine Änderung des JVM-Befehlssatzes erforderlich, was sehr schwerwiegend ist.
[2]. [Wie man Generika in Java einführt]
Um Generika zu nutzen, ohne sie tatsächlich einzuführen, verwendet Java einen generischen Löschmechanismus zur Einführung von Generika. Generika in Java werden nur vom Compiler javac verwendet, um die Datensicherheit zu gewährleisten und die Probleme einer erzwungenen Typkonvertierung zu vermeiden. Sobald die Kompilierung jedoch abgeschlossen ist, werden alle Typen im Zusammenhang mit Generika gelöscht.
[3]. [Klasse kann keine Typen ausdrücken, die sich auf Generika beziehen]
Daher werden parametrisierte Typen im Zusammenhang mit Generika, Typvariablentypen, generisch qualifizierte parametrisierte Typen (einschließlich Platzhalter + Platzhalter-qualifizierter Ausdrücke) und generische Array-Typen alle in ihrer ursprünglichen Form zurückgegeben und in der Bytecode-Datei gespeichert nachdem Generics gelöscht wurden und keine Bytecodedatei vorhanden ist, die mit ihrem eigenen Typ übereinstimmt. Daher können neu erweiterte Typen im Zusammenhang mit Generika nicht in der Class-Klasse vereinheitlicht werden.
(4). Darstellung von Typen im Zusammenhang mit Generika in Java
Um diese Typen durch Reflexion zu betreiben und den Anforderungen der tatsächlichen Entwicklung gerecht zu werden, hat Java ParameterizedType, GenericArrayType, TypeVariable und WildcardType hinzugefügt, um Typen darzustellen, die nicht in die Class-Klasse eingeordnet werden können, aber denselben Namen wie der ursprüngliche Typ haben.
(5). Einführung von Typ: Vereinheitlichung von Typen im Zusammenhang mit Generika und primitiven Typklassen
[Grund für die Einführung des Typs]
Für die Skalierbarkeit des Programms wurde schließlich die Type-Schnittstelle als allgemeine übergeordnete Schnittstelle für Class, ParameterizedType, GenericArrayType, TypeVariable und WildcardType eingeführt. Auf diese Weise akzeptiert der Typ-Typ-Parameter die tatsächlichen Parameter der oben genannten fünf Untertypen oder der Rückgabewerttyp ist der Typ-Typ-Parameter.
[Der Grund, warum es in der Typschnittstelle keine Methode gibt]
Aus dem oben Gesagten ist ersichtlich, dass die Entstehung von Type nur die Rolle der Verbesserung der Programmskalierbarkeit durch Polymorphismus spielt und keine anderen Auswirkungen hat. Daher gibt es im Quellcode der Type-Schnittstelle keine Methoden.