反序列化的serialVersionUID字段讲解

serialVersionUID是什么?

1、大家在进行对象的序列化和反序列化的时候,都有可能或多或少见过这个字段。
private final static long serialVersionUID = 12345679L
其实它的主要作用就是为了保证版本的兼容和唯一性,具体可以参考:serialVersionUID【需要进入文档的Serializable类】
2、它的主要两种用途就是:
1)将对象的字节序列保存在硬盘中
2)在网络上传输对象的字节序列

下面通过几个例子来讲解

通过将对象保存在文件中,并读取对象来进行讲解:

1)如果没有serialVersionUID,修改对象字段,并将对象读出会怎么样?

//定义一个需要序列化的类
public class Student implements Serializable {
    private String name;

    private String sex;
   /*省略setter和getter方法*/
}
进行序列化
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("d:/a.txt"));
Student student = new Student();
student.setSex("15");
objectOutputStream.writeObject(student);

进行对象的存储之后
为Student新增一个字段:public String id;
然后进行反序列化:

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:/a.txt"));
Student student1 = (Student)objectInputStream.readObject();

那么编译器将会出现异常:

Exception in thread "main" java.io.InvalidClassException: test.Student; local class incompatible: stream classdesc serialVersionUID = -5352512218071311753, local class serialVersionUID = -2551984491754459997

2)如果有serialVersionUID,但是在读出对象之前修改了serialVersionUID会怎么样

Student类:
public class Student implements Serializable {
	private final static long serialVersionUID = 123456789L;
	
    private String name;

    private String sex;
   /*省略setter和getter方法*/
}
进行序列化:
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("d:/a.txt"));
Student student = new Student();
student.setSex("15");
objectOutputStream.writeObject(student);

但是在反序列化之前,将Student中的serialVersionUID值修改为任意其他值,再次进行。
那么依旧会出现上述的异常

Exception in thread "main" java.io.InvalidClassException: test.Student;

3)如果存在serialVersionUID,然后修改对象字段,并将对象读出会怎么样?

Student类:

public class Student implements Serializable {

    private final static long serialVersionUID = 123456789L;

    private String name;

    private String sex;
 /*省略setter和getter方法*/
 }
 序列化:
 ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("d:/a.txt"));
 Student student = new Student();
student.setName("你猜");
student.setSex("15");
objectOutputStream.writeObject(student);
    

在进行反序列化之前,为Student类添加一个private String id字段

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:/a.txt"));
Student student1 = (Student)objectInputStream.readObject();
System.out.println(student1.toString()+"-->"+student1.id);

运行结果为:
在这里插入图片描述
注意:新添加的字段被赋值为默认值了

所以如果你想要自己修改之后的新版本可以兼容老版本,就需要使用相同的serialVersionUID的值来标识。但是如果你不想使得新版本和老版本形成一个映射关系,就可以修改为不相同的serialVersionUID值

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值