首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用FastJSON反序列化异常:无法将字段设置为java.lang.Exception

用FastJSON反序列化异常:无法将字段设置为java.lang.Exception
EN

Stack Overflow用户
提问于 2022-03-29 03:12:37
回答 1查看 373关注 0票数 0

我使用FastJSON来序列化和反序列化一些类。但是,我发现了一个不起作用的组合:包含对来自另一个类的对象的引用的异常不能反序列化。示例:

代码语言:javascript
复制
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
    }
}

此示例将产生以下运行时错误:

代码语言:javascript
复制
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。还是我犯了个错误?是什么导致了这一问题,为了避免这一问题,必须改变什么?

EN

回答 1

Stack Overflow用户

发布于 2022-03-29 06:51:21

当反序列化一个throwable时,FastJSON首先实例化throwable对象,然后设置它的属性。为了实例化对象,它查找三个不同的构造函数:

  1. 默认构造函数(无参数)
  2. 构造函数,并将错误消息作为输入。
  3. 构造函数,并将错误消息和原因作为输入。

如果所有这些都不可用,则默认为实例化Exception对象。

但是,我没有定义上述任何一个构造函数。因此,FastJSON实例化了一个Exception对象。稍后,它尝试将该异常对象的属性.a设置为A实例的引用。这是不起作用的,因为Exception没有这样的属性。

此外,我的内部类被声明为私有类,因此FastJSON无法访问它们。

解决办法很简单:

  1. 创建所需的构造函数
  2. 使课程公开
代码语言:javascript
复制
public static class E extends Exception {
    private A a;
    
    public E(String message, Throwable cause) {
        super(message, cause);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71656009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档