1. 程式人生 > >Serializable序列化為什麼要使用SerialversionUID

Serializable序列化為什麼要使用SerialversionUID

  • 為什麼要序列化物件
  • 為什麼要使用SerialversionUID
  • 怎麼生成SerialversionUID
  • 附:如何生成UUID

參考文章:【GraceJava--Java物件序列化為什麼要使用SerialversionUID

為什麼要序列化物件

把物件轉換為位元組序列的過程稱為物件的序列化。 
把位元組序列恢復為物件的過程稱為物件的反序列化。 
  物件的序列化主要有兩種用途: 
  1) 把物件的位元組序列永久地儲存到硬碟上,通常存放在一個檔案中; 
  2) 在網路上傳送物件的位元組序列。

  在很多應用中,需要對某些物件進行序列化,讓它們離開記憶體空間,入住物理硬碟,以便長期儲存。比如最常見的是Web伺服器中的Session物件,當有 10萬用戶併發訪問,就有可能出現10萬個Session物件,記憶體可能吃不消,於是Web容器就會把一些seesion先序列化到硬碟中,等要用了,再把儲存在硬碟中的物件還原到記憶體中。

  當兩個程序在進行遠端通訊時,彼此可以傳送各種型別的資料。無論是何種型別的資料,都會以二進位制序列的形式在網路上傳送。傳送方需要把這個Java物件轉換為位元組序列,才能在網路上傳送;接收方則需要把位元組序列再恢復為Java物件 

為什麼要使用SerialversionUID

簡單看一下 Serializable介面的說明 

  • 如果使用者沒有自己宣告一個serialVersionUID,介面會預設生成一個serialVersionUID 
  • 但是強烈建議使用者自定義一個serialVersionUID,因為預設的serialVersinUID對於class的細節非常敏感,反序列化時可能會導致InvalidClassException這個異常。 
  • (比如說先進行序列化,然後在反序列化之前修改了類,那麼就會報錯。因為修改了類,對應的SerialversionUID也變化了,而序列化和反序列化就是通過對比其SerialversionUID來進行的,一旦SerialversionUID不匹配,反序列化就無法成功。在實際的生產環境中,我們可能會建一系列的中間Object來反序列化我們的pojo,為了解決這個問題,我們就需要在實體類中自定義SerialversionUID。 )
 * If a serializable class does not explicitly declare a serialVersionUID, then
 * the serialization runtime will calculate a default serialVersionUID value
 * for that class based on various aspects of the class, as described in the
 * Java(TM) Object Serialization Specification.
 *
 * However, it is <em>strongly
 * recommended</em> that all serializable classes explicitly declare
 * serialVersionUID values, since the default serialVersionUID computation is
 * highly sensitive to class details that may vary depending on compiler
 * implementations, and can thus result in unexpected

怎麼生成SerialversionUID

可序列化類可以通過宣告名為 "serialVersionUID" 的欄位(該欄位必須是靜態 (static)、最終 (final) 的 long 型欄位)顯式宣告其自己的 serialVersionUID

兩種顯示的生成方式(當你一個類實現了Serializable介面,如果沒有顯示的定義serialVersionUID,Eclipse會提供這個提示功能告訴你去定義 。在Eclipse中點選類中warning的圖示一下,Eclipse就會自動給定兩種生成的方式。)

  •  一個是預設的1L,比如:private static final long serialVersionUID = 1L; 
  • 一個是根據類名、介面名、成員方法及屬性等來生成一個64位的雜湊欄位,比如:private static final   long     serialVersionUID = xxxxL;

附:如何生成UUID

UUID是1.5中新增的一個類,在java.util下,用它可以產生一個號稱全球唯一的ID

UUID(Universally Unique Identifier)全域性唯一識別符號,是指在一臺機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。按照開放軟體基金會(OSF)制定的標準計算,用到了乙太網卡地址、納秒級時間、晶片ID碼和許多可能的數字。由以下幾部分的組合:當前日期和時間(UUID的第一個部分與時間有關,如果你在生成一個UUID之後,過幾秒又生成一個UUID,則第一個部分不同,其餘相同),時鐘序列,全域性唯一的IEEE機器識別號(如果有網絡卡,從網絡卡獲得,沒有網絡卡以其他方式獲得),UUID的唯一缺陷在於生成的結果串會比較長。 

package com.mytest;
import java.util.UUID;
public class UTest {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println(uuid);
    }
}