Gson-具有值的Kotlin枚举的很好的序列化

时间:2019-06-02 09:10:12

标签: json serialization kotlin gson

我有一个带有值的枚举

enum class Foo(val serverVal:Int) {
     BAR(1),
     BUG(2)
}
我想与一个类一起使用的

data class C1(val fooVal:Foo)

我希望能够使用看起来尽可能接近的代码对其进行序列化:

Gson().toJson(C1(Foo.BAR))

那会产生

{"fooVal":1}

当然不是{"fooVal":"BAR"},而是默认转换。如果它是一个字符串值,我本可以使用@SerializedName,但我不能,因为它是一个Int而不是String。

是否有一种简单的方法可以向Foo中添加内容,以向Gson展示如何从Foo条目而不是其名称中获取Int值?

我在Java中看到的示例包括EnumAdapterFactory和TypeAdapter,它们非常笨重,并且破坏了编写漂亮代码的目的。

我很想获得一个在数据结构内部维护的解决方案。

enum class SomeEnum(val i:Int) {
   V1(1), V2(10), V3(5);

companion object {
   @SerializeMeLikeThis
   fun toJson() = i;

   @DeserializeMeLikeThat
   fun fromJson(v:Int) = values().find{it.i == v}?:whatever
}
}

一种丑陋的方式,但仍然是封闭的

data class C2(@SerializedName("foo") var serverFoo:Int) {
    // Becomes a nightmare with many params.
    constructor(f:Foo) : this(F.serverVal)
    var foo:Foo 
      get() = Foo.values().find{serverFoo == it.serverVal}?:whatever
      set(v) { serverFoo = v.serverVal }
}

因此可以称为

Gson().toJson(C2(BAR))

// Result: Foo.BAR
Gson().fromJson("""{"foo":"1"}""", C2::class.java).foo

好吧,你可以活下去...但是它...:-(

有什么好方法吗?

谢谢

0 个答案:

没有答案