Esto resuelve el problema:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
La primera línea crea una expresión de objeto que desciende TypeToken
y luego obtiene Java Type
de eso. Entonces el Gson().fromJson
método necesita el tipo especificado para el resultado de la función (que debe coincidir con el TypeToken
creado). Dos versiones de este trabajo, como arriba o:
val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)
Para facilitar la creación TypeToken
, puede crear una función auxiliar, que debe estar en línea para que pueda usar parámetros de tipo reificado :
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
Que luego se puede usar de cualquiera de estas formas:
val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()
Y todo el proceso se puede envolver en una función de extensión para la Gson
instancia:
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
Para que puedas llamar a Gson y no preocuparte por TypeToken
nada:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
Aquí Kotlin está usando la inferencia de tipos de un lado de la asignación o del otro, y genéricos reificados para que una función en línea pase a través del tipo completo (sin borrado), y lo usa para construir un TypeToken
y también hacer la llamada a Gson
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type