Hintergrund: Wir alle wissen, dass Generika im Wesentlichen „Typparameter“ von Typen bereitstellen. Sie werden auch als parametrisierte Typen oder parametrische Polymorphie bezeichnet. Tatsächlich wurde die Idee von Generika nicht zuerst in Java eingeführt. Vorlagen in C++ sind ein Beispiel für die Verwendung von Generika.
(Empfohlenes Video: Java-Video-Tutorial)
GJ (Generic Java) ist Eine Erweiterung der Java-Sprache, einer Java-Sprache mit parametrisierten Typen. In GJ geschriebene Programme sehen im Grunde genauso aus wie gewöhnliche Java-Programme, außer dass sie über mehr parametrisierte Typen und weniger Typkonvertierungen verfügen. Tatsächlich werden diese GJ-Programme zunächst in normale Java-Programme ohne Generika konvertiert und dann verarbeitet. Der Compiler schließt die Übersetzung von generischem Java in normales Java automatisch ab.
Wir alle wissen, dass der Compiler beim Kompilieren der Quelle eine generische Löschung durchführen kann Programm (Java-Code mit Generika), generische Typinformationen verwenden, um die Typsicherheit sicherzustellen, eine große Anzahl von Typsicherheitseinschränkungen überprüfen, die ohne Generika nicht überprüft würden, und gleichzeitig diese Typinformationen im generierten Bytecode löschen. Lassen Sie es uns zuerst überprüfen:
public static void main(String[] args) { ArrayList<Integer> ints = new ArrayList<Integer>(); ints.add(1); ints.add(2); ints.add(3); ArrayList<String> sts = new ArrayList<String>(); sts.add("a"); sts.add("b"); sts.add("c"); System.out.println(ints.getClass() == sts.getClass()); }
Das oben gedruckte Ergebnis ist wahr, weil
Nach dem Verständnis kann der ursprüngliche Wert nach dem generischen Löschen nicht wiederhergestellt werden. Die Typen sind alles in Form eines Objekts. Ist das wirklich der Fall?
Sehen Sie sich den folgenden Code an:
import java.lang.reflect.ParameterizedType;import java.util.ArrayList;import java.util.List;public class ClassTest { public static void main(String[] args) throws Exception { ParameterizedType type = (ParameterizedType) Bar.class.getGenericSuperclass(); System.out.println(type.getActualTypeArguments()[0]); ParameterizedType fieldType = (ParameterizedType) Foo.class.getField("children").getGenericType(); System.out.println(fieldType.getActualTypeArguments()[0]); ParameterizedType paramType = (ParameterizedType) Foo.class.getMethod("foo", List.class) .getGenericParameterTypes()[0]; System.out.println(paramType.getActualTypeArguments()[0]); System.out.println(Foo.class.getTypeParameters()[0] .getBounds()[0]); } class Foo<E extends CharSequence> { public List<Bar> children = new ArrayList<Bar>(); public List<StringBuilder> foo(List<String> foo) {return null; } public void bar(List<? extends String> param) {} } class Bar extends Foo<String> {} }
Drucken Sie
class java.lang.Stringclass com.javapuzzle.davidwang456.ClassTest$Barclass java.lang.Stringinterface java.lang.CharSequence
aus. Sie werden feststellen, dass jeder Typparameter beibehalten wird und zur Laufzeit über den Reflexionsmechanismus abgerufen werden kann. Was genau ist also „Typlöschung“? Zumindest wurde etwas gelöscht, oder? Ja. Tatsächlich wird alles außer strukturierten Informationen gelöscht – hier beziehen sich strukturierte Informationen auf Informationen, die sich auf die Struktur der Klasse und nicht auf den Ablauf der Programmausführung beziehen. Mit anderen Worten: Metadaten, die sich auf die Klasse, ihre Felder und die Typparameter ihrer Methoden beziehen, bleiben erhalten und können durch Reflektion abgerufen werden.
Dieser Artikel stammt von der chinesischen PHP-Website, Spalte Java-Tutorial, willkommen zum Lernen!
Das obige ist der detaillierte Inhalt vonKann die Java-Typ-Löschung wirklich alle Informationen vollständig löschen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!