使用 GSON 将 JSON 反序列化为 Enum

urg*_*as9 5 java enums gson

我的目标是将 JSON 文件或其一部分解析为 Java 中的 Enum 类。我可以轻松完成,但出于调试原因,我也想包含一个默认值。

public enum MyEnum {
    @SerializedName("texts")
    TEXTS,
    @SerializedName("buttons")
    BUTTONS,
    @SerializedName("inputs")
    INPUTS,
    DEFAULT
}
Run Code Online (Sandbox Code Playgroud)

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

{enum: "buttons"}
Run Code Online (Sandbox Code Playgroud)

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

{enum: "divider"}
Run Code Online (Sandbox Code Playgroud)

我仍然想知道它的价值。我想将所有值(例如“divider”、“line”、“color”...)DEFAULT映射到(维护映射到该DEFAULT值的字符串)。是否可以将价值“分隔符”保存到MyEnum.DEFAULT财产中?

Tim*_*mos 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,反序列化器(以及序列化器)的实现使用mapFrom枚举的方法。副作用是DEFAULT实例始终在全局范围内具有最新值,因此如果使用范围比调试更广泛,我不会推荐这种方法,而且说实话,我不希望其他程序员理解我编写此代码的原因。

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

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