java - GSON fromJson 返回 LinkedHashMap 而不是 EnumMap

标签 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());
    }
}

但是,我得到以下信息

toJSon : {"Malaysia":"RM","UnitedStates":"USD"}
fromJSon : {Malaysia=RM, UnitedStates=USD}
fromJSon : class java.util.LinkedHashMap

即使我使用了 new TypeToken<EnumMap<Country, String>>(){}.getType()具体我想要EnumMap而不是 LinkedHashMap

如何让 gson 返回 EnumMap ?

最佳答案

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

This interface is implemented to create instances of a class that does not define a no-args constructor. If you can modify the class, you should instead add a private, or public no-args constructor. However, that is not possible for library classes, such as JDK classes, or a third-party library that you do not have source-code of. In such cases, you should define an instance creator for the class. Implementations of this interface should be registered with GsonBuilder.registerTypeAdapter(Type, Object) method before Gson will be able to use them.

下面是一些示例代码:

实例创建器:

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

测试代码:

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

关于java - GSON fromJson 返回 LinkedHashMap 而不是 EnumMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16127904/

相关文章:

Android:使用 GSON 解析带有动态字段的响应

java - JSONObject 删除空值对

java - Cloud Speech API 返回代码=UNAUTHENTICATED,原因=java.io.IOException : Error getting access token for service account:

java - Java图形编程绘制图像错误

java - JSON gson 解析为\n

java - SharedPreferences 数据分布在每个 fragment 上

Java SQL 循环遍历字符串列表[]

java - ModelMapper,将实体列表映射到 DTO 对象列表

java - 如何使用 GSON 解析 JSON WHen 对象是 JSONObject 或 JSONArray

java - 为什么在启动 Spring Boot 应用程序时会出现 Gson 构建器错误?