Java | 原来 serialVersionUID 的用处在这里

一直不太明白Java对象里 serialVersionUID 字段是做什么用的。
有或者没有,它们之间有差别吗?除了Eclipse里提示的那个黄色的警告。

今天终于知道,原来是在对象序列化这块有作用。

看个例子。

有这样一个对象 User:

 1 class User implements Serializable {
 2 
 3     String username;
 4     int age;
 5     String gender;
 6     Date regDay;
 7     boolean martialStatus;
 8 
 9     @Override
10     public String toString() {
11         return "User [username=" + username + ", age=" + age + ", gender=" + gender + ", regDay=" + regDay
12                 + ", martialStatus=" + martialStatus + "]";
13     }
14 
15 }

 

现在将这个对象序列化存储到硬盘上:

 1 public void testWriteObject() {
 2     User user = new User();
 3     
 4     user.username = "Jack";
 5     user.password = "1234567";
 6     user.age = 20;
 7     user.gender = "male";
 8     user.regDay = new Date();
 9     user.martialStatus = false;
10     
11     // 文件的后缀名不影响,无论是 txt,io,甚至是没有后缀
12     ObjectSerialize.writeObject(user, "d:\\tmp\\obj");
13 }

注: ObjectSerialize 是笔者自己封装的简单的对对象序列化存取的工具类。
下同。

 

从对应的文件中读取对象信息:

1 public void testReadObject() {
2     User user = (User) ObjectSerialize.readObject("d:\\tmp\\obj");
3     System.out.println(user);
4 }

 

目前为止都是正常的。能够存储对象,也能够正确地读取对象信息。

假如,User对象又新增了一个国籍(nationality)字段,新的User类如下(主要差别是在第 8 行的新增字段):

 1 class User implements Serializable {
 2 
 3     String username;
 4     int age;
 5     String gender;
 6     Date regDay;
 7     boolean martialStatus;
 8     String nationality; // 新增的字段
 9 
10     @Override
11     public String toString() {
12         return "User [username=" + username + ", age=" + age + ", gender=" + gender + ", regDay=" + regDay
13                 + ", martialStatus=" + martialStatus + ", nationality=" + nationality + "]";
14     }
15

 

这个时候再去读区原来的对象文件,你会得到一个异常信息:

java.io.InvalidClassException: org.young.elearn.io.User; local class incompatible: stream classdesc serialVersionUID = 7967476135812239100, local class serialVersionUID = 905986497687499238

 

 serialVersionUID  的问题!!!
文件里存储的User对象的 serialVersionUID 跟当前的User对象(User.class)的 serialVersionUID 不一致。因为如果一个Java对象没有指定 serialVersionUID ,那么系统(JVM)动态地指定一个。

为了解决这个问题,只要在定义User对象时指定 serialVersionUID 就可以了,即:

1 class User implements Serializable {
2 
3     private static final long serialVersionUID = 7967476135812239100L;
4 
5     // same code as before
6 
7 }

 

详细的代码可参考:GitHub

 

阅读原文

posted on 2016-06-04 20:01  Memory4Young  阅读(1526)  评论(0编辑  收藏  举报

导航