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);
}
}