Java generisches Methodentypargument

8

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?

    
Tamás Cseh 01.07.2014, 09:49
quelle

4 Antworten

0

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%     
Tamás Cseh 29.09.2017, 07:26
quelle
1

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:

%Vor%

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.

    
Maurizio Cimadamore 06.10.2016 17:50
quelle
0

Um verschiedene Klassen zu deserialisieren, die ContentItem implementieren, müssen Sie eine benutzerdefinierte GSON-Instanz mit einem TypeAdapter verwenden.

Ссылка

    
koush 14.07.2014 08:06
quelle
-1

Was ist mit der Verwendung

? %Vor%

Da die Klassen die ContentItem-Schnittstelle implementieren erweitern die Schnittstelle

nicht     
RScottCarson 07.07.2014 13:50
quelle

Tags und Links