Ich habe ein Problem mit den expliziten Argumenttypen der generischen Methode. Ich weiß, dass ich das tun kann:
%Vor%unter der Annahme, dass es ein
gibt %Vor%Funktion in der Foo-Klasse. Das genaue Problem ist:
Ich möchte einige Inhalte herunterladen (Android mit Ion )
Diese Inhalte sind ähnlich (Artikel, BlogArticle, ...), alle implementieren eine ContentItem-Schnittstelle
Im Moment sieht der Download so aus:
Nachrichten zum Beispiel
%Vor%Wenn ich Blog-Artikel herunterladen möchte, muss ich nur URL- und Article-Klasse (für BlogArticle) ändern.
Ich habe versucht, eine generische Funktion wie folgt zu erstellen:
%Vor%und rufe diese Funktion
auf %Vor%Es ist in Ordnung, kompilieren Sie gut. Nach dem Laufen bekomme ich
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap kann nicht in com.my.packagename.model.ContentItem
umgewandelt werden
Das Problem ist, dass es nicht die explizite Klasse zum Zuordnen von Json zu pojo verwendet.
Können Sie mir eine generische Lösung vorschlagen?
Jahre später, aber ich dachte, dass es für jemanden nützlich sein kann. Ich habe eine einfachere Lösung gefunden. Es ist nur eine einfache, abgeschnittene Version, aber Sie können die Idee bekommen:
%Vor%Und verwende wie:
%Vor% Ich denke, es gibt keine Möglichkeit, das, was Sie wollen, mit dem TypeToken-Ansatz generisch zu implementieren. Beachten Sie, dass Typ-Token nur funktionieren können, wenn Sie eine anonyme innere Klasse erstellen. Auf diese Weise erstellen Sie effektiv eine neue Klassendatei, deren Supertyp als List<Article>
verdinglicht wird. Mit anderen Worten, es ist wie wenn Sie die folgende Erklärung hätten:
Wenn Sie die obige Deklaration selbst schreiben würden, würden Sie beobachten, dass die Klassendatei ArticleToken.class den generischen Supertyp im Attribut Signature
verfolgt (siehe JVMS ). Mit diesem Trick können Sie später auf diesen allgemeinen Supertyp zugreifen, indem Sie Class.getGenericSupertype
aufrufen. Mit anderen Worten, es ist ein Idiom gefälschte Generika zu fälschen.
Wenn Sie Ihren Code in eine generische Methode umwandeln und Artikel durch die Typvariable T ersetzen, geschieht Folgendes: Der von Ihnen erstellte Typ-Token ist wie folgt:
%Vor% Also wird die Information über T wie in der Klassendatei gespeichert, und wenn reflectiopn nach dem generischen Supertyp des Typs token fragt, erhalten Sie einfach TypeToken<List<T>>
zurück und nicht TypeToken<List<Article>>
, was Sie erwarten würden das Problem, das Sie sehen. Was Sie tun müssen, um dies zu tun, sind echte, vergiftete Generika, bei denen die Bindung von T an Article auf der Methodenaufrufseite das Laufzeitverhalten von new TypeToken<List<T>>
beeinflussen würde - leider ist dies bei Java nicht der Fall, der gelöschte Generics verwendet.
Was ist mit der Verwendung
? %Vor%Da die Klassen die ContentItem-Schnittstelle implementieren erweitern die Schnittstelle
nicht