其他分享
首页 > 其他分享> > fastjson对象的序列化与反序列化踩得坑

fastjson对象的序列化与反序列化踩得坑

作者:互联网

现象

最近使用RabbitMq发送消息时,遇到了提供者发送的消息(使用fastjson序列化数据对象)在消费者端转成(使用fastjson反序列化)数据对象后,属性缺失了

发送的消息对象:

/**
 * 课本
 **/
@Data
public class Book implements Serializable {

    private static final long serialVersionUID = -4861445364356803601L;

    private Integer id;
    private String name;
    private Integer type;
    private String remark;

    public Book(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
}

产生的现象如下图所示:

序列化对象后:

反序列化后:

上述现象可以看出,反序列化对象后,type 和 remark 属性值缺失了

原因

这里之所以出现这个问题,根本原因就是使用fastjson序列化与反序列化对象造成的,下面通过示例结合源码来分析一下成因:

1、无默认构造方法时,只有部分参数构造方法时(即只有 id,name 两个参数构成的构造方法)

对象:

运行断点调试:

运行结果:

得出结论:无默认构造方法时,构造bean属性从构造方法的参数中获取的(即只有id、name),因此反序列化时生成的对象会缺失 type 和 remark 的值

2、无默认构造方法时,有不同参数个数的多个构造方法

对象:

运行调试步骤如下图:

运行结果:

得出结论:无默认构造方法时,构造bean的属性使用最多参数(即有id、name、type、remark全部参数)的构造方法的所有参数,因此这里反序列化之后对象属性值没有缺失

3、有默认构造方法时,同时也有其他构造方法

对象:

运行调试步骤如下图:

运行结果:

得出结论:有默认构造方法时,优先使用默认构造方法,构造bean属性也是从所有的set方法中解析的,因此这里反序列化之后对象属性值不会缺失

最终结论

最后结论总结下来就2句话:

1、有默认构造方法时,优先使用默认构造方法,构造bean属性从所有的set方法中解析

2、无默认构造方法时,使用最多参数的构造方法,构造bean属性从最多参数构造方法中获取

解决方案

1、新建对象时最好加上默认构造方法

2、如果不想写默认构造方法,则需要写拥有所有参数的构造方法

源码

阅读的源码类(JavaBeanInfo)及方法(build):com.alibaba.fastjson.util.JavaBeanInfo#build(java.lang.Class<?>, java.lang.reflect.Type, com.alibaba.fastjson.PropertyNamingStrategy, boolean, boolean, boolean)

标签:fastjson,name,构造方法,对象,踩得,默认,序列化,id
来源: https://blog.csdn.net/ywlmsm1224811/article/details/97269539