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的值,由於這會引發兼容性的問題。