前言
本文介绍Java的序列化与反序列化,以及它们的应用。
什么是序列化与反序列化
序列化:将堆内存中的Java对象数据通过序列化机制被表示为字节序列。
反序列化:将字节序列恢复成Java对象。
为什么需要序列化
将对象序列化为字节序列便于存储到磁盘文件中或者进行网络传输。例如,在分布式系统中,JavaBean对象需要共享数据,此时为了便于对象在网络上传输,我们需要将对象数据转化为字节序列;对象只有在JVM运行时,对象才存在于内存中,但是在实际应用中,我们需要将业务数据以对象的方式进行保存。
transient关键字与序列化
对象进行序列化时,保存的是对象的状态,即对象的成员变量。若变量由static或transient进行修饰,则不会对该变量进行序列化。哪些变量需要transient关键字进行修饰?可以根据实例中其他字段计算出该字段,例如,可以通过当前时间和出生年月计算某个人的年龄,而不用序列化age这个字段,根据需求进行具体分析。
serialVersionUID
让我们来考虑一个问题,在序列化操作完成后,我们需要对序列化后对象增加成员变量,此时若进行反序列化会报错。
为了解决这个问题,在序列化时需要增加serialVersionUID字段,指定序列化版本号,当版本号相同,即使修改了对象的成员变量,对象也可以准确的反序列化。
实例
首先,定义一个User类
1 | public class User implements Serializable {//序列化实现的一种方式:实现Serializable接口 |
接下来,将序列化User的实例对象,再进行反序列化构建对象
1 | public class SerializableTest { |
输出结果:
1 | User{name='twentytwoguns', age=23, pwd=123456} |
若此时,需要对User类增加性别属性sex
1 | public class User implements Serializable { |
在进行上述的反序列化操作时,会有异常:
因为在保存User对象后修改了User的结构,会导致serialVersionUID的值发生变化,在反序列化的时候就会出错。解决的方法是在User类中增加一个serialVersionUID变量固定序列化的版本号。
1 | private static final long serialVersionUID = 7981560250804078637l; |