我使用FastJSON来序列化和反序列化一些类。但是,我发现了一个不起作用的组合:包含对来自另一个类的对象的引用的异常不能反序列化。示例:
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
public class Main {
@AllArgsConstructor
@Getter
@Setter
private static class A {
private String a;
private String b;
}
@AllArgsConstructor
@Getter
@Setter
private static class E extends Exception {
private A a;
}
public static void main(String[] args) {
E original = new E(new A("hello", "world"));
String serialized = JSON.toJSONString(original);
E deserialized = JSON.parseObject(serialized, E.class); // throws below exception
}
}此示例将产生以下运行时错误:
Exception in thread "main" com.alibaba.fastjson.JSONException: set property error, com.example.Main$E#a
at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:183)
at com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer.deserialze(ThrowableDeserializer.java:149)
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:688)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:396)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:300)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:573)
at com.example.Main.main(Main2.java:40)
Caused by: java.lang.IllegalArgumentException: Can not set com.example.Main$A field com.example.Main$E.a to java.lang.Exception
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
at java.lang.reflect.Field.set(Field.java:764)
at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:178)
... 6 more它告诉我,它不能将E中的字段E设置为Exception对象。它看起来像FastJSON中的一个bug,因为我希望它将a的值反序列化为A的对象,而不是E。还是我犯了个错误?是什么导致了这一问题,为了避免这一问题,必须改变什么?
发布于 2022-03-29 06:51:21
当反序列化一个throwable时,FastJSON首先实例化throwable对象,然后设置它的属性。为了实例化对象,它查找三个不同的构造函数:
如果所有这些都不可用,则默认为实例化Exception对象。
但是,我没有定义上述任何一个构造函数。因此,FastJSON实例化了一个Exception对象。稍后,它尝试将该异常对象的属性.a设置为A实例的引用。这是不起作用的,因为Exception没有这样的属性。
此外,我的内部类被声明为私有类,因此FastJSON无法访问它们。
解决办法很简单:
public static class E extends Exception {
private A a;
public E(String message, Throwable cause) {
super(message, cause);
}
}https://stackoverflow.com/questions/71656009
复制相似问题