使用GSON进行Kotlin通用值对象序列化

时间:2018-03-22 15:42:37

标签: serialization kotlin gson

例如,我有下一个课程

abstract class X<out T>(val x: T)

data class Y(val y: String = "y") : X<String>(x = "x")

class Holder(
     val  value: X<String>
)

我尝试使用gson序列化:

val gson = Gson()

val x = Holder(Y())
val json = gson.toJson(x)

我已经{"value":{"x":"x"}}但我需要{"value":{"x":"x", "y":"y"}}

2 个答案:

答案 0 :(得分:0)

如果对象类型在声明站点已知或以其他方式指定,则Gson不会分析实际的对象类/类型。 我不做Kotlin,但这种行为也可以用旧的Java重现:

abstract class X<T> {
    private final T x;
    X(final T x) {
        this.x = x;
    }
}

final class Y extends X<String> {
    private final String y;
    Y(final String x, final String y) {
        super(x);
        this.y = y;
    }
}

final class Holder {
    private final X<String> value; // value is considered known in advance here
    Holder(final X<String> value) {
        this.value = value;
    }
}

您必须向Holder类添加类型参数,例如Holder<T>T value,并在序列化/反序列化之前指定实际的类型参数化。

gson.toJson(holder, new TypeToken<Holder<X<?>>>() {}.getType())

生成{"value":{"x":"x"}}X 已知是此处的类型),但是:

gson.toJson(holder, new TypeToken<Holder<Y>>() {}.getType())

生成{"value":{"y":"y","x":"x"}}。很抱歉不知道在科特林如何做到这一点。

答案 1 :(得分:0)

要解决这个问题,我们需要使用gson extras中的RuntimeTypeAdapterFactory和init gson之类的

    val gson = GsonBuilder()
            .registerTypeAdapterFactory(
                    RuntimeTypeAdapterFactory.of(X::class.java)
                            .registerSubtype(Y::class.java)
            )
            .create()