Heim  >  Artikel  >  Java  >  So verwenden Sie TypeToken in Java

So verwenden Sie TypeToken in Java

王林
王林nach vorne
2023-05-16 08:49:051698Durchsuche

Generisches Löschen

Wie wir alle wissen, sind die generischen Typen von Java nur zur Laufzeit gültig, das heißt, List sind alle vom Typ List

Warum diesen Implementierungsmechanismus wählen? Kannst du es nicht einfach löschen? Zehn Jahre nach der Geburt von Java wollte ich ein Konzept implementieren, das den C++-Vorlagen ähnelt, nämlich Generika. Die Klassenbibliothek von Java ist ein sehr wertvolles Gut im Java-Ökosystem. Sie muss Abwärtskompatibilität (dh vorhandener Code und Klassendateien sind weiterhin zulässig) und Migrationskompatibilität (generalisierter Code und nicht generalisierter Code können sich gegenseitig aufrufen) gewährleisten Aufgrund dieser beiden Hintergründe und Überlegungen haben Java-Designer eine Kompromissimplementierungsmethode der „Typlöschung“ übernommen.

Gleichzeitig gibt es einen solchen „Loch“-Mechanismus, der uns daran hindert, zur Laufzeit bestimmte Arten generischer Parameter nach Belieben abzurufen.

Typetoken

students, die verwendet haben, müssen bei der Deserialisierung einen Type -typetoken -Typ definieren, wie diese

private Type type = new TypeToken<List<Map<String, Foo>>>(){}.getType();  //调用fromJson方法时把type传过去,如果type的类型和json保持一致,则可以反序列化出来  gson.fromJson(json, type);

dhree Fragen

1 ? Wie oben erwähnt, wenn Sie die Typen List> direkt übergeben, aber weil die Laufzeitgenerika gelöscht werden, erhalten Sie tatsächlich List, dann weiß der nachfolgende Gson nicht, was er braucht Um sie in den Typ Map zu konvertieren, konvertiert Gson sie standardmäßig in den Typ LinkedTreeMap.

2. Warum gibt es geschweifte Klammern {}? Diese Zahnspange ist das A und O. Wie wir alle wissen, wird in diesem Zusammenhang in der Java-Syntax {} verwendet, um eine anonyme Klasse zu definieren. Diese anonyme Klasse erbt die TypeToken-Klasse, die eine Unterklasse von TypeToken ist.

3. Warum sollten wir den generischen Typ durch Unterklassen erhalten? Dies ist der Schlüssel dafür, dass TypeToken den generischen Typ erhalten kann. Dies ist eine clevere Methode. Die Idee ist wie folgt: Da die Generika in List gelöscht werden, verwende ich eine Unterklasse. SubList erweitert List. Welche Art von Typ wird in diesem Fall gespeichert? ?

Die Generika der übergeordneten Klasse, die meine Unterklasse erben muss, wurden tatsächlich bestimmt, die JVM speichert diesen Teil der Informationen und er wird in den Klasseninformationen der Unterklasse gespeichert.

Wie erhalten wir diese Informationen? Glücklicherweise bietet Java eine API:

Type mySuperClass = foo.getClass().getGenericSuperclass();  Type type = ((ParameterizedType)mySuperClass).getActualTypeArguments()[0];  System.out.println(type);
Zusammenfassend wird für Klassen mit Generika ein ParameterizedType-Objekt zurückgegeben, für Object, Schnittstellen und primitive Typen wird null zurückgegeben und für Array-Klassen wird Object.class zurückgegeben. ParameterizedType ist ein Java-Typ, der einen Typ mit generischen Parametern darstellt. Nach der Einführung von Generics in JDK1.5 implementieren alle Klassen in Java die Type-Schnittstelle.

Debuggen Sie es selbst und Sie werden wissen, was es zurückgibt.

Prinzip

Die Kernmethode sind die beiden gerade erwähnten Sätze, der Rest ist sehr einfach. Werfen wir einen Blick auf die getType-Methode von TypeToken

public final Type getType() {   //直接返回type      return type;    }
Sehen Sie sich die Initialisierung von type

//注意这里用了protected关键字,限制了只有子类才能访问  protected TypeToken() {      this.type = getSuperclassTypeParameter(getClass());      this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);      this.hashCode = type.hashCode();    }      //getSuperclassTypeParameter方法    //这几句就是上面的说到    static Type getSuperclassTypeParameter(Class<?> subclass) {      Type superclass = subclass.getGenericSuperclass();      if (superclass instanceof Class) {        throw new RuntimeException("Missing type parameter.");      }      ParameterizedType parameterized = (ParameterizedType) superclass;      //这里注意一下,返回的是Gson自定义的,在$Gson$Types里面定义的TypeImpl等,这个类都是继承Type的。      return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);    }
an

Das obige ist der detaillierte Inhalt vonSo verwenden Sie TypeToken in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen