Questo risolve il problema:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
La prima riga crea un'espressione oggetto che discende da TypeToken
e quindi ottiene il Java Type
da quella. Quindi il Gson().fromJson
metodo richiede il tipo specificato per il risultato della funzione (che dovrebbe corrispondere a quello TypeToken
creato). Due versioni di questo lavoro, come sopra o:
val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)
Per semplificare la creazione di TypeToken
è possibile creare una funzione di supporto, che deve essere in linea in modo che possa utilizzare parametri di tipo reificati :
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
Che può quindi essere utilizzato in uno di questi modi:
val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()
E l'intero processo può essere avvolto in una funzione di estensione per l' Gson
istanza:
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
In modo che tu possa semplicemente chiamare Gson e non preoccuparti TypeToken
affatto:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
Qui Kotlin sta usando l'inferenza del tipo da un lato dell'assegnazione o dall'altro, e generici reificati per una funzione inline per passare attraverso il tipo completo (senza cancellazione), e lo usa per costruire TypeToken
e anche fare la chiamata a Gson
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type