Enum类型及其json序列化

1,233 阅读1分钟
enum class EnumTypeTest{
    ONE,
    TWO
}

实际上,这个声明定义的类型是一个类,它刚好有2个实例。编译器翻译成的字节码和下面的声明类似:

class EnumTypeTest: Enum{
    public static ONE = EnumTypeTest(),
    public static TWO = EnumTypeTest()
}

枚举类型可以附带参数:

enum class EnumTypeTest(val code: Int){
    ONE(0),
    TWO(1)
}

enum和Gson

默认序列化的结果:

fun main(){
    val data = Data(EnumType.ONE)
    val result = Gson().toJson(data)
    print(result)    //{"et":"ONE"}
}

enum class EnumTypeTest(val code : Int){
    ONE(1),
    TWO(2)
}

data class Data(
    val et: EnumTypeTest? = null,
): Serializable

使用SerializedName的结果:

enum class EnumTypeTest(val code : Int){
     @SerializedName("1")
     ONE(1),
     @SerializedName("2")
     TWO(2)
}
//{"et":"1"}

@SerializedName为什么会起作用

对于Enum类型,Gson最终会使用EnumTypeAdapter将其值转变成json字符串。

例如,对于Gson.toJson(EnumTypeTest.ONE)最终会调用EnumTypeAdapter. write(out, EnumTypeTest.ONE)来序列化:



private static final class EnumTypeAdapter{
  ...
  public EnumTypeAdapter(Class<T> classOfT) {
      for (T constant : classOfT.getEnumConstants()) {
        String name = constant.name();
        SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class);
        if (annotation != null) {
          name = annotation.value();
        }
        constantToName.put(constant, name);
      }
      ...
  }

  public void write(JsonWriter out, T value) {
    out.value(value == null ? null : constantToName.get(value));
  }
}