简体   繁体   English

使用GSON将JSON反序列化为Enum

[英]Deserialize JSON using GSON to Enum

My goal is to parse a JSON file or part of it to an Enum class in Java. 我的目标是将JSON文件或其中的一部分解析为Java中的Enum类。 I can do it easily, but for debugging reasons I would like to include a default value as well. 我可以轻松地做到这一点,但出于调试原因,我想包括一个默认值。

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

So if I try to parse this JSON (using a wrapper class): 所以,如果我尝试解析这个JSON(使用包装类):

{enum: "buttons"}

I would get MyEnum.BUTTONS , but if I try to parse: 我会得到MyEnum.BUTTONS ,但如果我尝试解析:

{enum: "divider"}

I would still like to know the value. 我仍然想知道它的价值。 I would like to map all values (eg "divider", "line", "color",...) to DEFAULT (maintaining the String which mapped to the DEFAULT value). 我想将所有值(例如“divider”,“line”,“color”,...)映射到DEFAULT (保持映射到DEFAULT值的String)。 Would it be possible to save value "divider" to MyEnum.DEFAULT property? 是否可以将值“divider”保存到MyEnum.DEFAULT属性?

Implement a custom JsonDeserializer and install it using GsonBuilder.registerTypeAdapter . 实现自定义JsonDeserializer并使用GsonBuilder.registerTypeAdapter安装它。 Your enum implementation could then be implemented as follows: 然后可以按如下方式实现您的枚举实现:

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;
    }
}

The implementation of your deserializer (and serializer, too) then uses the mapFrom method of your enum. 然后,您的反序列化器(以及序列化器)的实现将使用枚举的mapFrom方法。 The side effect is that the DEFAULT instance always has the latest value on a global scope, so I wouldn't recommend this approach if used wider than debugging, and to be honest I wouldn't expect another programmer to understand why I wrote this. 副作用是DEFAULT实例总是在全局范围内具有最新值,所以如果使用比调试更广泛的话我不推荐这种方法,说实话我不希望其他程序员理解为什么我写这个。

However, if you extract the serialized forms of your enums out of the enum definition, then in your deserializer you need to implement a switch that decides which enum to deserialize into. 但是,如果从枚举定义中提取枚举的序列化形式,那么在反序列化器中,您需要实现一个开关来决定要反序列化的枚举。 If you also separate your debugging code and call it from your deserializer, you don't need the serialized form in your enum anymore. 如果您还将调试代码分开并从反序列化器中调用它,则不再需要枚举中的序列化表单。 Moreover, you separate different functionality - the Single Responsibility Principle . 此外,您将不同的功能分开 - 单一责任原则

The only other option left is using a non-enum class, so you can instantiate new objects upon deserialization time. 剩下的唯一选择是使用非枚举类,因此您可以在反序列化时实例化新对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM