使用GSON将JSON反序列化为枚举

时间:2016-04-19 11:19:24

标签: java enums gson

我的目标是将JSON文件或其中的一部分解析为Java中的Enum类。我可以很容易地做到这一点,但出于调试原因,我也希望包含一个默认值。

public enum MyEnum {
    @SerializedName("texts")
    TEXTS,
    @SerializedName("buttons")
    BUTTONS,
    @SerializedName("inputs")
    INPUTS,
    DEFAULT
}

因此,如果我尝试解析此JSON(使用包装类):

{enum: "buttons"}

我会得到MyEnum.BUTTONS,但如果我尝试解析:

{enum: "divider"}

我仍然想知道这个价值。我想将所有值(例如“divider”,“line”,“color”,...)映射到DEFAULT(保持映射到DEFAULT值的String)。是否可以将值“divider”保存到MyEnum.DEFAULT属性?

1 个答案:

答案 0 :(得分:1)

实施自定义JsonDeserializer并使用GsonBuilder.registerTypeAdapter进行安装。然后可以按如下方式实现您的枚举实现:

public enum MyEnum {
    TEXTS ("texts"),
    BUTTONS("buttons"),
    INPUTS("inputs"),
    DEFAULT(null);

    private String text;

    private MyEnum (String text) {
        this.text = text;
    }

    public String getValue () {
        return text;
    }

    public static MyEnum mapFrom (String serialized) {
        if (serialized == null) {
            DEFAULT.text = null;
            return DEFAULT;
        }
        for (MyEnum inst : MyEnum.values()) {
            if (serialized.equals(inst.getValue())) {
                return inst;
            }
        }
        DEFAULT.text = serialized;
        return DEFAULT;
    }
}

然后,您的反序列化程序(以及序列化程序)的实现将使用枚举的mapFrom方法。副作用是DEFAULT实例总是在全局范围内具有最新值,所以如果使用比调试更广泛的话我不推荐这种方法,说实话我不希望其他程序员理解为什么我写了这个。

但是,如果从枚举定义中提取枚举的序列化形式,那么在反序列化器中,您需要实现一个开关来决定要反序列化的枚举。如果您还将调试代码分开并从反序列化器中调用它,则不再需要枚举中的序列化表单。此外,您将不同的功能分开 - Single Responsibility Principle

剩下的唯一选择是使用非枚举类,因此您可以在反序列化时实例化新对象。