5

我有两个要使用 Google Gson 库序列化为 JSON 的 HashMap:

    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 没有?

4

1 回答 1

6

Gson 使用反射,并不关心一个类是否实现了Serializable. 但是,Gson 确实需要一个无参数构造函数(请参阅设计文档):

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不会在输出中。

于 2013-05-28T05:52:11.653 回答