GSON fromJson返回LinkedHashMap而不是EnumMap

Che*_*eng 7 java gson

我想让gson能够返回一个EnumMap对象.我使用以下代码

package sandbox;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.EnumMap;
import java.util.Map;

/**
 *
 * @author yccheok
 */
public class Sandbox {

    public static void main(String[] args) throws InterruptedException {    
        testGson();
    }

    public static enum Country {
        Malaysia,
        UnitedStates
    }

    public static void testGson() {
        Map<Country, String> enumMap = new EnumMap<Country, String>(Country.class);
        enumMap.put(Country.Malaysia, "RM");
        enumMap.put(Country.UnitedStates, "USD");
        Gson gson = new Gson();
        String string = gson.toJson(enumMap);
        System.out.println("toJSon : " + string);
        enumMap = gson.fromJson(string, new TypeToken<EnumMap<Country, String>>(){}.getType());
        System.out.println("fromJSon : " + enumMap);
        System.out.println("fromJSon : " + enumMap.getClass());
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我得到以下内容

toJSon : {"Malaysia":"RM","UnitedStates":"USD"}
fromJSon : {Malaysia=RM, UnitedStates=USD}
fromJSon : class java.util.LinkedHashMap
Run Code Online (Sandbox Code Playgroud)

即使我已经习惯new TypeToken<EnumMap<Country, String>>(){}.getType()了我想要的EnumMap而不是LinkedHashMap

怎么让gson回来EnumMap

Per*_*ion 10

即使使用类型标记,Gson也只能将数据反序列化为具有默认构造函数的类.并且EnumMap没有(它需要使用其元素匹配的枚举类型进行实例化).解决此问题的最简单方法是定义并使用InstanceCreator:

实现此接口以创建未定义no-args构造函数的类的实例.如果您可以修改类,则应该添加私有或公共无参数构造函数.但是,对于库类(例如JDK类)或者没有源代码的第三方库,这是不可能的.在这种情况下,您应该为类定义实例创建者.在Gson能够使用它们之前,应该使用GsonBuilder.registerTypeAdapter(Type,Object)方法注册此接口的实现.

下面是一些示例代码:

InstanceCreator:

class EnumMapInstanceCreator<K extends Enum<K>, V> implements
        InstanceCreator<EnumMap<K, V>> {
    private final Class<K> enumClazz;

    public EnumMapInstanceCreator(final Class<K> enumClazz) {
        super();
        this.enumClazz = enumClazz;
    }

    @Override
    public EnumMap<K, V> createInstance(final Type type) {
        return new EnumMap<K, V>(enumClazz);
    }
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

final Gson gson = new GsonBuilder().registerTypeAdapter(
        new TypeToken<EnumMap<Country, String>>() {
        }.getType(),
        new EnumMapInstanceCreator<Country, String>(Country.class))
        .create();

final Map<Country, String> enumMap = new EnumMap<Country, String>(
        Country.class);
enumMap.put(Country.Malaysia, "RM");
enumMap.put(Country.UnitedStates, "USD");
String string = gson.toJson(enumMap);
System.out.println("toJSon : " + string);

final Map<Country, String> reverseEnumMap = gson.fromJson(string,
        new TypeToken<EnumMap<Country, String>>() {
        }.getType());
System.out.println("fromJSon (Class): " + reverseEnumMap.getClass());
System.out.println("fromJSon : " + reverseEnumMap);
Run Code Online (Sandbox Code Playgroud)

  • 抱歉.使用最新的gson 2.2.3非常完美. (3认同)