java 中的 serialVersionUID

  • private static final long serialVersionUID = 1L;
  • Java的序列化機制是經過判斷類的serialVersionUID來驗證版本一致性的。
    • 在進行反序列化時,
    • JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,
    • 若是相同就認爲是一致的,能夠進行反序列化,
    • 不然就會出現序列化版本不一致的異常,便是InvalidCastException

具體的序列化過程是這樣的java

  • 序列化操做的時候系統會把當前類的serialVersionUID寫入到序列化文件中,
  • 當反序列化時系統會去檢測文件中的serialVersionUID,判斷它是否與當前類的serialVersionUID一致,
    • 若是一致就說明序列化類的版本與當前類版本是同樣的,能夠反序列化成功,不然失敗。

serialVersionUID有兩種顯示的生成方式:        spa

  • 一是默認的1L,好比:private static final long serialVersionUID = 1L;        
  • 二是根據類名、接口名、成員方法及屬性等來生成一個64位的哈希字段
  • 當實現java.io.Serializable接口的類沒有顯式地定義一個serialVersionUID變量時候,
    • Java序列化機制會根據編譯的Class自動生成一個serialVersionUID做序列化版本比較用,
    • 這種狀況下,若是Class文件(類名,方法明等)沒有發生變化(增長空格,換行,增長註釋等等),
      • 就算再編譯屢次,serialVersionUID也不會變化的。

狀況一:假設Person類序列化以後,從A端傳輸到B端,而後在B端進行反序列化。code

  • 在序列化Person和反序列化Person的時候,
    • A端和B端都須要存在一個相同的類。
  • 若是兩處的serialVersionUID不一致,會產生什麼錯誤呢?
    • Exception in thread "main" java.io.InvalidClassException: com.sf.code.serial.Person; local class incompatible: stream classdesc serialVersionUID = 1234567890, local class serialVersionUID = 123456789
          at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:621)
          at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
          at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
          at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
          at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
          at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
          at com.sf.code.serial.DeserialTest.main(DeserialTest.java:13)

       

狀況二:假設兩處serialVersionUID一致,對象

  • 若是A端增長一個字段,而後序列化,而B端不變,而後反序列化,會是什麼狀況呢?
    • 最後的結果爲:執行序列化,反序列化正常,可是A端增長的字段丟失(被B端忽略)。

狀況三:假設兩處serialVersionUID一致,若是B端減小一個字段,A端不變,會是什麼狀況呢?接口

  • 【答案】序列化,反序列化正常,B端字段少於A端,A端多的字段值丟失(被B端忽略)。

狀況四:假設兩處serialVersionUID一致,若是B端增長一個字段,A端不變,會是什麼狀況呢?it

  • 說明序列化,反序列化正常,B端新增長的int字段被賦予了默認值0。io

靜態變量序列化

  • 緣由在於序列化時,並不保存靜態變量
  • 這其實比較容易理解,序列化保存的是對象的狀態,靜態變量屬於類的狀態,所以 序列化並不保存靜態變量。
相關文章
相關標籤/搜索