Answers:
创建此内联乐趣:
inline fun <reified T> Gson.fromJson(json: String) = fromJson<T>(json, object: TypeToken<T>() {}.type)
然后您可以通过以下方式调用它:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
先前的选择:
替代方案1:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
您必须object :
输入特定类型fromJson<List<Turns>>
替代方案2:
正如@cypressious提及的那样,也可以通过以下方式实现:
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
用于:
val turnsType = genericType<List<Turns>>()
这样可以解决问题:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
第一行创建一个对象表达式,该对象表达式从该对象派生而来TypeToken
,然后从中获取Java Type
。然后,该Gson().fromJson
方法要么需要为函数结果指定的类型(应与TypeToken
创建的结果匹配)。此作品的两个版本,如上所述或:
val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)
为了使创建起来更容易,TypeToken
您可以创建一个辅助函数,该函数必须是内联的,以便可以使用经过修饰的类型参数:
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
然后可以通过以下两种方式之一使用它:
val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()
整个过程可以包装到Gson
实例的扩展函数中:
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
这样您就可以致电Gson,而完全不用担心TypeToken
:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
Kotlin在这里使用的是从赋值一侧或另一侧的类型推断,并对内联函数使用经过泛化的泛型来传递完整类型(不删除),并使用该泛型构造a TypeToken
并调用Gson
Gson().fromJson<kotlin.List<Turns>>(pref.turns)
Gson()
还是Gson
静态实例?您需要第一个实例。
另一个选择(不确定它看起来比其他的看起来更优雅)可能是这样的调用:
turns = Gson().fromJson(allPurchasesString, Array<Turns>::class.java).toMutableList()
因此,您使用的是Java Array类的一个内衬而不是“ pure Kotlin”。
我使用了类似这样的方法来转换T
为string
&String
回到T
using Gson
。并非完全符合您的要求,以防万一。
声明扩展
inline fun <reified T : Any> T.json(): String = Gson().toJson(this, T::class.java)
inline fun <reified T : Any> String.fromJson(): T = Gson().fromJson(this,T::class.java)
用法
// Passing an object to new Fragment
companion object {
private const val ARG_SHOP = "arg-shop"
@JvmStatic
fun newInstance(shop: Shop) =
ShopInfoFragment().apply {
arguments = Bundle().apply {
putString(ARG_SHOP, shop.json())
}
}
}
// Parsing the passed argument
private lateinit var shop: Shop
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
shop = it.getString(ARG_SHOP).fromJson() ?: return
}
}
这同样有效,并且更简单
inline fun <reified T> Gson.fromJson(json: String) : T =
this.fromJson<T>(json, T::class.java)
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type