1. Einführung in Java Generics
Generics sind eine neue Funktion von Java 1.5. Das Wesentliche an Generics ist ein parametrisierter Typ, was bedeutet, dass der zu bedienende Datentyp als Parameter angegeben wird. Dieser Parametertyp kann bei der Erstellung von Klassen, Schnittstellen und Methoden verwendet werden, die als generische Klassen, generische Schnittstellen bzw. generische Methoden bezeichnet werden.
Der Vorteil der Einführung von Java-Generika besteht darin, dass sie sicher und einfach sind.
Vor Java SE 1.5 wurden die „willkürlichen“ Parameter durch Verweisen auf den Typ „Object“ implementiert. Der Nachteil von „willkürlich“ bestand darin, dass eine explizite Typkonvertierung erforderlich war, und diese Konvertierung erfordert die Bitten Sie den Entwickler, den tatsächlichen Parametertyp im Voraus zu kennen. Bei erzwungenen Typkonvertierungsfehlern löst der Compiler möglicherweise keinen Fehler aus und es tritt während der Laufzeit eine Ausnahme auf. Dies stellt ein Sicherheitsrisiko dar.
Der Vorteil von Generika besteht darin, dass die Typsicherheit während der Kompilierung überprüft wird und alle Umwandlungen automatisch und implizit erfolgen, was die Wiederverwendung von Code verbessert.
Es gibt einige Regeln und Einschränkungen bei der Verwendung von Generika:
1 Die Typparameter von Generika können nur Klassentypen (einschließlich benutzerdefinierter Klassen) sein, nicht jedoch ein einfacher Typ.
2. Derselbe generische Typ kann mehreren Versionen entsprechen (da der Parametertyp unsicher ist) und verschiedene Versionen generischer Klasseninstanzen nicht kompatibel sind.
3. Generics können mehrere Typparameter haben.
4. Generische Parametertypen können beispielsweise die Extens-Anweisung verwenden. Üblicherweise werden sie zu „begrenzten Typen“.
5. Generische Parametertypen können auch Platzhaltertypen sein.
Class<?> classType = Class.forName(java.lang.String);
Generika haben auch Schnittstellen, Methoden usw. Es gibt viele Inhalte und es erfordert viel Aufwand, sie zu verstehen und geschickt anzuwenden.
2. Java-Generika-Implementierungsprinzip: Typlöschung
Java-Generika sind Pseudo-Generika. Beim Kompilieren werden alle generischen Informationen gelöscht. Die erste Voraussetzung für das richtige Verständnis des Konzepts der Generika ist das Verständnis der Typlöschung.
Generics in Java werden grundsätzlich auf Compiler-Ebene implementiert. Die Typinformationen in Generics sind nicht im generierten Java-Bytecode enthalten. Bei der Verwendung von Generika hinzugefügte Typparameter werden vom Compiler während der Kompilierung entfernt. Dieser Vorgang wird als Typlöschung bezeichnet.
Im Code definierte Typen wie List
3. Der ursprüngliche Typ, der nach der Typlöschung erhalten bleibt
Der ursprüngliche Typ (Rohtyp) ist der tatsächliche Typ der Typvariablen im Bytecode, nachdem die generischen Informationen gelöscht wurden. Immer wenn ein generischer Typ definiert wird, wird der entsprechende primitive Typ automatisch bereitgestellt. Typvariablen werden gelöscht (crased) und durch ihren qualifizierten Typ ersetzt (nicht qualifizierte Variablen sind Objekt).
class Pair<T> { private T value; public T getValue() { return value; } public void setValue(T value) { this.value = value; } }
Der ursprüngliche Typ von Pair
class Pair { private Object value; public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } }
Da T in Pair
Wenn die Typvariable begrenzt ist, wird der ursprüngliche Typ durch die erste begrenzende Typvariable ersetzt.
Wenn „Pair“ beispielsweise wie folgt deklariert wird:
public class Pair<T extends Comparable& Serializable> {
Dann ist der ursprüngliche Typ „Comparable“
Hinweis:
Wenn Pair wie diese Klasse als öffentlich deklariert wird Pair
Um zwischen primitiven Typen und generischen Variablentypen zu unterscheiden
Beim Aufruf einer generischen Methode können Sie einen generischen Typ angeben oder nicht.
Ohne Angabe eines Generikums ist der Typ der generischen Variablen die niedrigste Ebene derselben übergeordneten Klasse mehrerer Typen in der Methode, bis Object.
Bei der Angabe eines Generikums müssen mehrere Typen in der Methode der generische Instanztyp oder seine Unterklasse sein.
public class Test{ public static void main(String[] args) { /**不指定泛型的时候*/ int i=Test.add(1, 2); //这两个参数都是Integer,所以T为Integer类型 Number f=Test.add(1, 1.2);//这两个参数一个是Integer,以风格是Float,所以取同一父类的最小级,为Number Object o=Test.add(1, "asd");//这两个参数一个是Integer,以风格是Float,所以取同一父类的最小级,为Object /**指定泛型的时候*/ int a=Test.<Integer>add(1, 2);//指定了Integer,所以只能为Integer类型或者其子类 int b=Test.<Integer>add(1, 2.2);//编译错误,指定了Integer,不能为Float Number c=Test.<Number>add(1, 2.2); //指定为Number,所以可以为Integer和Float } //这是一个简单的泛型方法 public static <T> T add(T x,T y){ return y; } }
Tatsächlich ist es in einer generischen Klasse fast dasselbe, wenn der generische Typ nicht angegeben ist, außer dass der generische Typ zu diesem Zeitpunkt Object ist. Wenn beispielsweise in ArrayList der Wenn kein generischer Typ angegeben ist, kann jeder Objekttyp in ArrayList platziert werden.
4. C++-Vorlagenimplementierung
Obwohl ich C++ nicht verstehe, habe ich auch im Internet nach der Implementierung von C++ gesucht.
Das Erzeugen unterschiedlicher Typen für jede Instanziierung einer Vorlage in C++ ist ein Phänomen, das als „Aufblähen des Vorlagencodes“ bekannt ist.
Zum Beispiel vector
Weitere Artikel zu den Implementierungsprinzipien von Java-Generika finden Sie auf der chinesischen PHP-Website!