我有两个HashMaps使用Google Gson库序列化为JSON:
final Map<String, String> map1 = new HashMap<String, String>() {
{
put("abc", "def");
}
};
final Map<String, String> map2 = new HashMap<String, String>();
map2.put("abc", "def");
final Gson gson = new Gson();
final String s1 = gson.toJson(map1); // "null"
final String s2 = gson.toJson(map2); // {"abc":"def"}
为什么第二个HashMap正确序列化但不是第一个HashMap?
答案 0 :(得分:6)
Gson使用反射,并不关心类是否实现Serializable
。但是,Gson确实需要一个无参数构造函数(参见design doc):
Gson需要在反序列化之前创建一个虚拟类实例 Json数据进入其字段......我们通过调用它来创建类实例 无参数构造函数......
当您致电toJson(Object obj)
时,Gson将使用obj.getClass()
来确定如何构建obj
的“虚拟实例”,在您的情况下,这是一个匿名内部上课。内部类需要引用它们的包含类才能构造。序列化时无法引用外部类,这就是您的结果为null
的原因。您可以通过向Gson提供有关如何构造对象的更多信息来解决此问题:
final Map<String, String> map1 = new HashMap<String, String>() {
{
put("abc", "def");
}
};
Gson gson = new Gson();
String json = gson.toJson(map1, new TypeToken<Map<String, String>>() {}.getType()); // {"abc":"def"}
修改:请注意,这仅适用,因为您的匿名类可以转换为Map<String, String>
。如果你有一个更复杂的内部类,例如:
final Map<String, String> map1 = new HashMap<String, String>() {
private String additionalData = "Foo";
{
put("abc", "def");
}
};
additionalData
不在输出中。