gpt4 book ai didi

java - GSON 不会反序列化对外部类的引用

转载 作者:搜寻专家 更新时间:2023-10-31 19:55:45 25 4
gpt4 key购买 nike

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

public class A implements Serializable {

int attrParent;
List<B> items = new ArrayList<B>();

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失败。

有谁知道我该如何解决这个问题,即在反序列化该对象时将内部引用恢复为外部引用?

最佳答案

正如 Gson 文档所说:

Gson can serialize static nested classes quite easily.

Gson can also deserialize static nested classes. However, Gson can not automatically deserialize the pure inner classes since their no-args constructor also need a reference to the containing Object which is not available at the time of deserialization. You can address this problem by either making the inner class static or by providing a custom InstanceCreator for it.

将 B 更改为静态内部类是不可能的,因为您的方法需要引用 getSomeCalculationValue 中的外部类,因此,我已尝试使用 InstanceCreator< 解决您的问题 但解决方案有点难看,所以我建议你使用自定义反序列化。我稍微更改了您的 A 类,将项目设为公开,以便更轻松地创建我向您展示的示例。

public class ADeserializer implements JsonDeserializer<A> {
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接口(interface),JSON与Java序列化没有任何共同点
  2. 我的反序列化器缺少空案例管理,您应该完成空 JSON 或空字段。

关于java - GSON 不会反序列化对外部类的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19449761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com