serialVersionUID是在Java序列化、反序列化对象时起做用的一个字段。Java的序列化机制是经过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,若是相同就认为是一致的,能够进行反序列化,不然就会出现序列化版本不一致的异常,便是InvalidClassException。java
序列化是一种把对象持久化到外部的手段。在网络传输等场景中应用普遍,如Dubbo等框架。类经过实现 java.io.Serializable
接口以启用其序列化功能。apache
阿里规约中强制性的提醒,修改serialVersionUID字段,会引发反序列化失败的状况。网络
下面,经过实际代码,来演示对象序列化、反序列化的操做。app
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
复制代码
commons-lang3这个包有帮咱们实现了序列化的工具类,commons-io帮咱们实现了文件操做的工具类,junit用来写单元测试。框架
有User.class以下:工具
@Data
@Builder
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
}
复制代码
@Data 和 @Builder 是Lombok里面的注解,能够自动生成getter、setter方法等,不懂的能够查看我以前的文章,对这个有讲解。单元测试
须要序列化的类,须要实现Serializable接口,Serializable是一个标识接口,里面没有具体须要实现的东西。测试
序列化代码:ui
@Test
public void serializeTest() throws IOException {
User user = User.builder().username("happyjava").build();
byte[] serialize = SerializationUtils.serialize(user);
FileUtils.writeByteArrayToFile(new File("serialize.txt"), serialize);
}
复制代码
SerializationUtils是commons-lang3包给咱们提供的工具类,它给咱们提供了序列化和反序列化的方法,咱们直接拿过来用就行了。spa
FileUtils是commons-io包给咱们提供的工具类,它给咱们提供了很是丰富的IO操做工具类。
执行方法后,查看serialize.txt:
这就是序列化后,保存到外部的对象了。咱们能够把它反序列化成为对象。
反序列化代码以下:
@Test
public void deserializeTest() throws IOException {
byte[] bytes = FileUtils.readFileToByteArray(new File("serialize.txt"));
Object object = SerializationUtils.deserialize(bytes);
System.out.println(object instanceof User);
User user = (User)object;
System.out.println(user.getUsername());
}
复制代码
这里使用FileUtils把外部的文件读入,使用SerializationUtils反序列化成为对象。而后判断反序列化后对象的类型,强转为User后输出其username,运行结果以下:
说明反序列化已经成功过了
如今把User的serialVersionUID值作一下修改:
@Data
@Builder
public class User implements Serializable {
private static final long serialVersionUID = 2L;
private String username;
}
复制代码
以前是1,如今改成2,再次执行反序列化方法,结果以下:
这里出现了开头提到的InvalidClassException异常,而且经过异常信息能够看到,这是serialVersionUID不一致引发的。
org.apache.commons.lang3.SerializationException: java.io.InvalidClassException: cn.happy.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
复制代码
经过理论和代码演示,咱们已经知道了serialVersionUID字段能够形成反序列化失败的状况。因此在作系统升级的时候,须要充分考虑是否要改动serialVersionUID的值,由于这会引发兼容性的问题。