如何在Kotlin中将TypeToken +泛型与Gson一起使用

m1m5dgzv  于 2022-11-06  发布在  Kotlin
关注(0)|答案(7)|浏览(209)

我无法从自定义类中获取泛型类型列表(Turns):

  1. val turnsType = TypeToken<List<Turns>>() {}.type
  2. val turns = Gson().fromJson(pref.turns, turnsType)

它说:

  1. cannot access '<init>' it is 'public /*package*/' in 'TypeToken'
sh7euo9m

sh7euo9m1#

创建此内联乐趣:

  1. inline fun <reified T> Gson.fromJson(json: String) = fromJson<T>(json, object: TypeToken<T>() {}.type)

你可以这样称呼它:

  1. val turns = Gson().fromJson<Turns>(pref.turns)
  2. // or
  3. val turns: Turns = Gson().fromJson(pref.turns)

先前的替代方案:

备选方案1:

  1. val turnsType = object : TypeToken<List<Turns>>() {}.type
  2. val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)

您必须将object :和特定类型放入fromJson<List<Turns>>

备选方案2:

正如@柏树提它也可以这样实现:

  1. inline fun <reified T> genericType() = object: TypeToken<T>() {}.type

用作:

  1. val turnsType = genericType<List<Turns>>()
展开查看全部
ha5z0ras

ha5z0ras2#

这样就解决了问题:

  1. val turnsType = object : TypeToken<List<Turns>>() {}.type
  2. val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)

第一行创建一个从TypeToken派生的对象表达式,然后从中获取Java Type。然后Gson().fromJson方法需要为函数的结果指定的类型(该类型应与创建的TypeToken匹配)。该方法有两个版本,如上所述或:

  1. val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)

为了更容易地创建TypeToken,您可以创建一个helper函数,该函数需要内联,以便它可以使用具体化类型参数:

  1. inline fun <reified T> genericType() = object: TypeToken<T>() {}.type

然后,可以通过以下任一方式使用它:

  1. val turnsType = genericType<List<Turns>>()
  2. // or
  3. val turnsType: List<Turns> = genericType()

整个过程可以封装到Gson示例的扩展函数中:

  1. inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)

这样,您就可以直接调用Gson,而完全不用担心TypeToken

  1. val turns = Gson().fromJson<Turns>(pref.turns)
  2. // or
  3. val turns: Turns = Gson().fromJson(pref.turns)

在这里,Kotlin从赋值语句的一端或另一端使用类型推断,并使用内联函数的具体化泛型来传递完整类型(没有擦除),并使用它来构造TypeToken,同时调用Gson

展开查看全部
pnwntuvh

pnwntuvh3#

另一个选项(不确定它看起来是否比其他选项更优雅)可能是这样的调用:

  1. turns = Gson().fromJson(stringObject, Array<Turns>::class.java).toMutableList()

因此,您使用的是java Array类one liner,而不是“纯Kotlin”。

0aydgbwb

0aydgbwb4#

  1. val obj: MutableList<SaleItemResponse> = Gson().fromJson(messageAfterDecrypt,
  2. object : TypeToken<List<SaleItemResponse>>() {}.type)

这是我在Kotlin中解析数据数组的方法。

kokeuurv

kokeuurv5#

我使用类似的东西来转换Tstring & String回到T使用Gson。不完全是你要找的,但以防万一。
正在声明扩展名

  1. inline fun <reified T : Any> T.json(): String = Gson().toJson(this, T::class.java)
  2. inline fun <reified T : Any> String.fromJson(): T = Gson().fromJson(this,T::class.java)

用途

  1. // Passing an object to new Fragment
  2. companion object {
  3. private const val ARG_SHOP = "arg-shop"
  4. @JvmStatic
  5. fun newInstance(shop: Shop) =
  6. ShopInfoFragment().apply {
  7. arguments = Bundle().apply {
  8. putString(ARG_SHOP, shop.json())
  9. }
  10. }
  11. }
  12. // Parsing the passed argument
  13. private lateinit var shop: Shop
  14. override fun onCreate(savedInstanceState: Bundle?) {
  15. super.onCreate(savedInstanceState)
  16. arguments?.let {
  17. shop = it.getString(ARG_SHOP).fromJson() ?: return
  18. }
  19. }
展开查看全部
qlckcl4x

qlckcl4x6#

这也是可行的,而且更简单

  1. inline fun <reified T> Gson.fromJson(json: String) : T =
  2. this.fromJson<T>(json, T::class.java)
uidvcgyl

uidvcgyl7#

使用以下代码将Gson的Kotlingeneric reified function反序列化为ArrayList<T>

  1. inline fun <reified T> get( ... ): ArrayList<T>{
  2. val str = "[{},{}]"
  3. val type = TypeToken.getParameterized(ArrayList::class.java, T::class.java).type
  4. val t = Gson().fromJson<ArrayList<T>>(str, type)
  5. return t
  6. }

相关问题