Java-Typ Generische als Argument für GSON
In GSON, um eine Liste von Objekten, die Sie tun
Gson gson = new Gson();
Type token = new TypeToken<List<MyType>>(){}.getType();
return gson.fromJson(json, token);
Funktioniert es Super, aber ich möchte noch weiter gehen und haben gleichen Typ eingestellt, so kann ich haben eine gemeinsame Funktion zu analysieren, Liste der Objekte, die mit diesem code
//the common function
public <T> List<T> fromJSonList(String json, Class<T> type) {
Gson gson = new Gson();
Type collectionType = new TypeToken<List<T>>(){}.getType();
return gson.fromJson(json, collectionType);
}
//the call
List<MyType> myTypes = parser.fromJSonList(jsonString, MyType.class);
Leider gibt ein array von StringMaps, nicht der Typ. T wird interpretiert als ein anderer generischer Typ, nicht mein Typ. Abhilfe ?
Vielleicht sind diese links hilfreich: stackoverflow.com/questions/75175/... stackoverflow.com/questions/356583/... velocityreviews.com/forums/... tutorials.jenkov.com/java-reflection/generics.html In der zweiten Verbindung, die Sie vorschlagen, eine factory-Methode. Hmm... ich bin mir nicht sicher, ob die Verwendung ? statt T könnte das problem lösen.
InformationsquelleAutor Rodrigo Asensio | 2013-01-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Generika Arbeit zur compile-Zeit. Der Grund super-Typ-Token arbeiten, ist da eine (anonyme) innere Klassen können auf die Art Argumente, um Ihre generischen Oberklassen (superinterfaces), die wiederum gespeichert sind, direkt in den bytecode Metadaten.
Sobald Ihr .java-Quelldatei kompiliert wird, der parameter type
<T>
ist offensichtlich weggeworfen. Da ist es zur Kompilierzeit nicht bekannt, es kann nicht gespeichert werden in bytecode, also ist es gelöscht und Gson kann es nicht Lesen.UPDATE
Nach newacct Antwort, ich habe versucht, das umzusetzen, was er vorgeschlagen hat in seiner option 2, dh die Umsetzung einer
ParameterizedType
. Der code sieht so aus (hier ist eine grundlegende test):der Zweck dieses code ist auf
getFromJsonList()
:Selbst wenn die Technik funktioniert und ist in der Tat sehr klug (ich wusste es nicht, und ich hätte nie thinked es), dies ist die Letzte Errungenschaft:
statt
Zu mir, alle, diese Verpackung in nutzlos, auch wenn ich damit einverstanden, dass
TypeToken
s den code schauen böse 😛Es ist. Der entscheidende Punkt ist, dass, um für die super-Typ-token-machinary zu arbeiten, wir müssen erstellen Sie eine fiktive anonyme Klasse, dh ein Teil der bytecode, der hat sogar seinen eigenen
Outer.$N.class
- Datei. Dies ist der trick, machtTypeToken
arbeiten, kann aber nicht wirklich in Ihrem Fall nicht, denn wenn die bereitgestellte Methode Quelle kompiliert wird, wird dieClass<T>
argument fofromJSonList
gelöschtEs ist nicht "gelöscht" in der
Type
. Eher, das generische argument wird gespeichert alsTypeVariable
eher als eineClass
vielleicht haben Sie falsch verstanden, der Satz. Ich meine, im inneren
fonrJsonList()
, dietype
argument ist ein raw -Class
.Souldn nicht
getRawType
zurückListOfSomething.class
statt? Ansonsten danke, das du mir den Arsch gerettet heute 🙂InformationsquelleAutor Raffaele
Seit
gson 2.8.0
, die Sie verwenden können,TypeToken#getParametized((Typ rawType, Typ... typeArguments))
zu erstellen, dietypeToken
, danngetType()
sollte den trick tun.Beispiel:
InformationsquelleAutor oldergod
Beispiel:
Super Antwort! Dank
Wie man für immer Singel-Objekt von <T>
Gute Antwort, aber bewusst sein, dass die
List
zurückgegebenArrays.asList
ist ein nur-lese-wrapper für das array. Es ist nicht eineArrayList
. Sie können nicht hinzufügen oder ändern von Elementen.InformationsquelleAutor kayz1
Habe ich Raffaele ist Ansatz einen Schritt weiter und generified der Klasse, so dass es funktioniert mit jeder Klasse A, wobei B eine nicht-parametrisierte Klasse. Könnte nützlich sein, für Sets und andere Sammlungen.
InformationsquelleAutor Christian Brüggemann
Hier ist der vollständige code-Basis auf Super Antwort von @oldergod
Mit
Hoffe, es hilft
InformationsquelleAutor Phan Van Linh
Diese beantwortet wurde in vorherigen Fragen. Grundsätzlich gibt es 2 Möglichkeiten:
Type
in der aufrufenden Seite. Der aufrufende code verwendenTypeToken
oder was auch immer, um es zu konstruieren.Type
entsprechend der parametrisierte Typ selbst. Dies erfordert, dass Sie eine Klasse schreiben, dieParameterizedType
fromJsonList()
- option 2 ist sehr clever statt. Ist dieser was meinst du?vielleicht. Oder Sie können kopieren Sie die Quelle der ParameterizedTypeImpl (wird intern von vielen Java-Bibliotheken) aus dem Internet
InformationsquelleAutor newacct
Wenn die Programmierung in kotlin, wir können
reified type parameter
im inline-FunktionUnd verwenden Sie wie unten im code
InformationsquelleAutor alijandro
Kotlin "ListOfSomething" - Lösung, die für mich gearbeitet:
InformationsquelleAutor Michael Peterson
In kotlin einfach verwenden, zum Beispiel:
Orte-Funktion
fun getPlaces<T> (jsonString : String, clazz: Class<T>) : T {
val places : T = Gson().fromJson(jsonString,clazz)
return places
}
Dann können Sie verwenden als:
InformationsquelleAutor Cristian Cardoso
Wenn verwenden:
InformationsquelleAutor Ahmad Aghazadeh