写点什么

Java | 原来 serialVersionUID 的用处在这里

用户头像
YoungZY
关注
发布于: 2020 年 06 月 12 日

本文首发于 http://www.YoungZY.com/


一直不太明白 Java 对象里 serialVersionUID 字段是做什么用的。

有或者没有,它们之间有差别吗?除了 Eclipse 里提示的那个黄色的警告。

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

看个例子。

有这样一个对象 User

class User implements Serializable {
String username; int age; String gender; Date regDay; boolean martialStatus;
@Override public String toString() { return "User [username=" + username + ", age=" + age + ", gender=" + gender + ", regDay=" + regDay + ", martialStatus=" + martialStatus + "]"; }
}
复制代码

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

public void testWriteObject() {	User user = new User();		user.username = "Jack";	user.password = "1234567";	user.age = 20;	user.gender = "male";	user.regDay = new Date();	user.martialStatus = false;		// 文件的后缀名不影响,无论是 txt,io,甚至是没有后缀	ObjectSerialize.writeObject(user, "d:\\tmp\\obj");}
复制代码

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


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

public void testReadObject() {	User user = (User) ObjectSerialize.readObject("d:\\tmp\\obj");	System.out.println(user);}
复制代码

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

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

class User implements Serializable {
String username; int age; String gender; Date regDay; boolean martialStatus; String nationality; // 新增的字段
@Override public String toString() { return "User [username=" + username + ", age=" + age + ", gender=" + gender + ", regDay=" + regDay + ", martialStatus=" + martialStatus + ", nationality=" + nationality + "]"; }
}
复制代码

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

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 就可以了,即:

class User implements Serializable {
private static final long serialVersionUID = 7967476135812239100L;
// same code as before
}
复制代码


相关链接


阅读原文

发布于: 2020 年 06 月 12 日阅读数: 64
用户头像

YoungZY

关注

http://www.youngzy.com 2018.11.14 加入

还未添加个人简介

评论

发布
暂无评论
Java | 原来 serialVersionUID 的用处在这里