1. 程式人生 > >Serializable序列化中serialVersionUId的作用

Serializable序列化中serialVersionUId的作用

Serializable是java所提供的一個序列化介面,它是一個空介面,為物件提供標準的序列化和反序列化操作,使用Serializable來實現序列化很簡單,只要在類的宣告中指定一個類似下面的標識即可自動實現預設的序列化過程。

private static final long serialVersionUID=2656653232L

想讓一個物件實現序列化,只要這個類實現Serializable介面並宣告一個serialVersionUID即可,實際上serialVersionUID也不是必須的,不宣告它同樣可以實現序列化,但是這將會對反序列化過程產生影響 serialVersionUID是用來輔助序列化和反序列化過程的,序列化的時候系統會把當前類的serialVersionUID寫入序列化的檔案中,當反序列化的時候系統會檢測當前檔案中的serialVersionUID是否和當前類的serialVersionUID一致,如果一致這個時候可以反序列化成功,否則就說明當前類和序列化的類相比發生了某些變換,比如成員變數的數量、型別可能發生了改變,這個時候是無法正常反序列化的

一般來說,我們應該手動指定serialVersionUID的值,比如1L,也可以讓Eclipse根據當前類的結構自動去生成他的hash值,這樣序列化和反序列化的serialVersionUID是相同的,因此可以正常反序列化。如果不手動指定serialVersionUID的值,反序列化時當前類有所改變,比如增加或減少了某些成員變數,那麼系統會重新計算當前類的hash值並把它賦值給serialVersionUID,這個時候當前類的serialVersionUID就和序列化資料中的serialVersionUID不一致,於是反序列化失敗,程式就會出現crash。所以當我們手動指定了serialVersionUID的值,就可以很大程度上避免了反序列化的失敗。但是如果類結構發生了非常規性改變,比如修改了類名,修改了成員變數的型別,這個時候儘管serialVersionUID驗證通過了,但是反序列化還是會失敗,因為類結構發生了毀滅性的改變。

注意:靜態成員變數不屬於物件,所以不會參與序列化過程。其次用transient關鍵字標記的成員變數不參與序列化過程。