我想让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
?
答案 0 :(得分: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);
}
}
测试代码:
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);