在我的Java应用程序中,我定义了两个类,名为A
和B
,其中B
是A
的内部类。两者都被定义为可序列化
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
失败。
有人知道我怎么能解决这个问题,那就是在反序列化这个对象时恢复内部到外部引用?
答案 0 :(得分:6)
正如Gson的文档所说:
Gson可以很容易地序列化静态嵌套类。
Gson也可以反序列化静态嵌套类。但是, Gson可以 因为它们不会自动反序列化纯内部类 no-args构造函数还需要对包含Object的引用 在反序列化时不可用。您可以 通过使内部类静态或通过使用来解决此问题 为它提供自定义InstanceCreator。
将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
最后两个笔记:
Serializable
接口,JSON与Java序列化没有任何共同之处