【问题标题】:How to implement polymorphic list deserialization with GSON in Kotlin?如何在 Kotlin 中使用 GSON 实现多态列表反序列化?
【发布时间】:2018-08-11 19:18:51
【问题描述】:

我有一个数据馈送返回一个列表,该列表可能是三种类型中的一种(说类型 A、B 和 C)。以上所有类型共享 2 个属性,其余属性特定于该类型。我尝试使用该模式。

abstract class Parent (val type: String, val id: String)

data class TypeA(override val type: String ... )
data class TypeB(override val type: String ... )

我正在使用 Retrofit 并尝试将列表反序列化为

List<? extends Parent>

在 Kotlin 中应该是什么

List<out Parent>

但是 GSON 在实例化抽象的父类时会引发反序列化错误。

java.lang.RuntimeException: Failed to invoke public com.XX.Parent() with no args

有什么想法可以在 Kotlin 中实现吗?

【问题讨论】:

  • 我认为您遗漏了更多异常消息?
  • 现在我为我的抽象类写了一个显式适配器,不确定它是否有效。

标签: android kotlin gson retrofit2 moshi


【解决方案1】:

由于您在问题中标记了 Moshi,我将提供一种使用 Moshi 的 PolymorphicJsonAdapterFactory 的方法。根据对象属性的值,您基本上可以将某些内容解析为不同的类型。

您要做的第一件事是将您的父类型声明为密封类,并让其他类型从它扩展:

sealed class Parent(val type: String){
    data class TypeA(override val type: String, ... ): Parent(type) 
    data class TypeB(override val type: String, ... ): Parent(type) 
}

现在你要告诉 Moshi 如何解析 Parent 对象。你这样做是注册一个PolymorphicJsonAdapterFactory

val moshi = Moshi.Builder()
      .add(PolymorphicJsonAdapterFactory.of(Parent::class.java, "type")
          .withSubtype(TypeA::class.java, "typeA")
          .withSubtype(TypeB::class.java, "typeB")
      .build()

这样,如果属性“type”的值为“typeA”,它将反序列化为TypeA 实例。与TypeB 一样,如果属性“type”是“typeB”

您可以在此处查看另一个示例: https://github.com/square/moshi/blob/master/adapters/src/main/java/com/squareup/moshi/adapters/PolymorphicJsonAdapterFactory.java

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    相关资源
    最近更新 更多