GSON没有反序列化对外层的引用

在我的Java应用程序中,我定义了两个类,称为AB ,其中BA内部类。 两者都被定义为可序列化

 public class A implements Serializable { int attrParent; List items = new ArrayList(); public void setAttrParent(int attrParent) { this.attrParent = attrParent; } public int getAttrParent() { return attrParent; } public class B implements Serializable { private int attr; public void setAttr(int attr) { this.attr = attr; } public int getAttr() { return attr; } public int getSomeCalculationValue() { return this.attr * A.this.attrParent; // Problems occurs here } } } 

使用GSON序列化此对象之前getSomeCalculationValue工作正常。 但是, 序列化和反序列化之后getSomeCalculationValue失败并出现NullPointerException

发生这种情况是因为内部类B不再具有对外部类A的引用,因此, A.this . A.this失败的。

有谁知道我怎么能解决这个问题,那就是在反序列化这个对象的同时恢复内部到外部的引用?

正如Gson的文档所说:

Gson可以很容易地序列化静态嵌套类。

Gson还可以反序列化静态嵌套类。 但是, Gson不能自动反序列化纯内部类,因为它们的no-args构造函数还需要对反序列化时不可用的包含Object的引用 。 您可以通过使内部类静态或为其提供自定义InstanceCreator来解决此问题。

将B更改为静态内部类是不可能的,因为你的方法需要在getSomeCalculationValue引用外部类,所以,我试图用InstanceCreator解决你的问题但是解决方案有点难看,所以我建议你使用一个自定义反序列化。 我稍微改变了你的A类,公开项目使我更容易创建我给你看的例子。

 public class ADeserializer implements JsonDeserializer { public A deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { A a = new A(); a.attrParent = json.getAsJsonObject().get("attrParent").getAsInt(); JsonArray ja = json.getAsJsonObject().get("items").getAsJsonArray(); for(JsonElement e: ja){ B b = a.new B(); b.setAttr(e.getAsJsonObject().get("attr").getAsInt()); a.items.add(b); } return a; } } 

这就是我使用它的方式:

 public class Q19449761 { public static void main(String[] args) { A a = new A(); a.setAttrParent(3); B b = a.new B(); b.setAttr(10); a.items.add(b); System.out.println("Before serializing: " + a.items.get(0).getSomeCalculationValue()); Gson g = new Gson(); String json = g.toJson(a, A.class); System.out.println("JSON string: " + json); A test2 = g.fromJson(json, A.class); try { System.out.println("After standard deserialization: " +test2.items.get(0).getSomeCalculationValue()); } catch (Exception e) { e.printStackTrace(); } GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(A.class, new ADeserializer()); A test3 = builder.create().fromJson(json, A.class); System.out.println("After custom deserialization: " + test3.items.get(0).getSomeCalculationValue()); } } 

这是我的执行:

 Before serializing: 30 JSON string: {"attrParent":3,"items":[{"attr":10}]} java.lang.NullPointerException at stackoverflow.questions.q19449761.A$B.getSomeCalculationValue(A.java:32) at stackoverflow.questions.q19449761.Q19449761.main(Q19449761.java:26) After custom deserialization: 30 

最后两个笔记:

  1. 您不需要实现Serializable接口,JSON与Java序列化没有任何共同之处
  2. 我的反序列化器缺少空案例管理,您应该完成null JSON或null字段。