【问题标题】:GSON serialization in Kotlin android, override propertyKotlin android中的GSON序列化,覆盖属性
【发布时间】:2018-03-07 17:59:54
【问题描述】:

我有一个 Retrofit 的默认响应类

open class DefaultResponseImpl : DefaultResponse {

    override val error: List<RestError>? get() = meta?.listErrors

    @Expose
    var meta: Meta? = null
}

而且这个 Meta 可以有一些额外的字段,所以我想用一些像这样的额外字段覆盖它

class SomeResponse : DefaultResponseImpl() {
    @SerializedName("meta")
    @Expose
    val metaLocal: MetaInner? = null

    inner class MetaInner : Meta() {
        @SerializedName("extra_field")
        @Expose
        val field: Long? = null
    }
}

但我收到错误java.lang.IllegalArgumentException: Unable to create converter for class com.responses.SomeResponse

怎么了? MetaInnerMeta 的子类型,我不会用另一种类型覆盖旧的元字段(这会在 IDE 中产生错误)。我只是添加了另一个必须从同一个 SerializedName 解析的字段

如何在 Kotlin 中实现这一点?

【问题讨论】:

    标签: android kotlin gson retrofit2


    【解决方案1】:

    我认为这取决于“元”键的冲突。 实际上 SomeResponse 类等价于这个类:

    class SomeResponse : DefaultResponse {
    
       override val error: List<RestError>? get() = meta?.listErrors
    
       @Expose
       var meta: Meta? = null
    
       @SerializedName("meta")
       @Expose
       val metaLocal: MetaInner? = null
    
       inner class MetaInner : Meta() {
         @SerializedName("extra_field")
         @Expose
         val field: Long? = null
       }
    }
    

    很容易观察到 meta 键同时用于变量 metametaLocal

    您可以为这两个请求使用一个唯一的类,使用泛型来传递 meta 属性的类型。

    open class DefaultResponseImpl<T> : DefaultResponse {
    
    override val error: List<RestError>? get() {
        if (meta? is Meta?) return meta?.listErrors
        return null
    }
    
    @Expose
    var meta: T = null
    }
    

    【讨论】:

    • Meta 对于所有响应都是相同的,我需要一些方法来扩展它,而不是创建十几个相同的兄弟类,它们在 1-2 个额外的字段中会有所不同
    • 好的。您可以将 meta 声明为私有,使用更通用的类型(JsonObject?JsonArray?)并覆盖 getter。
    • 或者你可以使用泛型来传递元属性类型
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多