Serialization
對許多 Java 開發人員來說
SerialVersionUID
始終是個謎。我經常看到關於什麼是 的問題
SerialVersionUID
,或者如果我不在
SerialVersionUID
我的類別中聲明會發生什麼
Serializable
?
除了令人困惑和不經常使用之外,這個問題的另一個原因是 Eclipse IDE 缺少警告
SerialVersionUID
,例如:「
Serialized 類別 Customer 沒有聲明long類型
Serializable
的static Final SerialVersionUID 欄位」long“)。在本文中,您不僅將了解 Java 的基礎知識,還將了解它對序列化和反序列化過程的影響。當您宣告一個類別(如透過實作令牌介面)時,Java 執行時間將使用預設序列化機制在磁碟上儲存該類別的實例,除非您將進程配置為使用
Externalized 介面。在序列化期間,Java 執行時會為此類別建立一個版本號,以便稍後可以反序列化。在 Java 中,此版本號稱為. 如果在反序列化期間沒有匹配,則進程將退出並在「」流中出現異常,並且還將列印類別名稱和相應的. 解決此問題的快速解決方案是將其複製並定義為類別中的類型常數。在這篇文章中,我們將了解為什麼要在Java中使用以及如何使用JDK的serialver工具來產生這個ID。如果您是序列化新手,您也可以觀看
Top 10 Java Serialization Interview Questions來評估您的知識並找到您理解中的差距以供進一步閱讀。與(並發)和(多線程)一樣,(序列化)是另一個值得閱讀多次的主題。
Customer
SerialVersionUID
SerialVersionUID
Serializable
java.io.Serializable
SerialVersionUID
SerialVersionUID
InvalidClassException
main
java.io.InvalidClassException
SerialVersionUID
SerialVersionUID
private
static
final
long
SerialVersionUID
Concurrency
Multi-threading
Serialization
為什麼在 Java 中使用 SerialVersionUID
正如我所說,當我們沒有在類別中定義值時,序列化機制將為我們做這件事
SerialVersionUID
。
static
final
long
這種機制對許多細節都很敏感,包括類別的字段、它們的存取修飾符、它實現的接口,甚至不同的編譯器實現;對類別的任何更改或使用不同的編譯器都可能產生不同的結果,
SerialVersionUID
這最終將導致阻止序列化資料被重新載入。依賴Java的序列化機制來產生這個id是有風險的,這就是為什麼在
SerialVersionUID
你的
Serialized類別中明確定義它是一個好主意。我強烈建議閱讀 Java 經典著作 -
Joshua Bloch 《Effective Java》,以了解 Java 序列化以及錯誤處理它們的問題。對了,JDK還提供了一個工具
serialver
,位於
JAVA_HOME目錄的
bin目錄下,在我的電腦上是
C:\Program Files\Java\jdk1.6.0_26\bin\serialver.exe,可以用來產生對於舊課程。如果您對類別進行的變更破壞了序列化並且您的應用程式無法重新載入序列化實例,則這非常有用。您可以輕鬆地使用此實用程式來建立舊實例,然後透過將該欄位聲明為
private static final long來明確使用它。順便說一句,出於效能和安全原因,強烈建議使用常規二進位格式進行序列化;同樣,「Effective Java」有幾個段落非常詳細地演示了常規格式的優點。
SerialVersionUID
SerialVersionUID
SerialVersionUID
如何使用serialver JDK實用程式產生SerialVersionUID
您可以使用
serialver
來產生
SerialVersionUID
類別。這對於開發類特別有用;該實用程式
SerialVersionUID
以易於複製的格式傳回。您可以使用
serialver
JDK 實用程序,如範例所示:
$ serialver
use: serialver [-classpath classpath] [-show] [classname...]
$ serialver -classpath . Hello
Class Hello is not Serializable.
$ serialver -classpath . Hello
Hello: static final long SerialVersionUID = -4862926644813433707L;
您也可以使用該實用程式
serialver
作為
GUI
命令
$ serialver –show
,這將開啟一個檢查器
serial version
,該檢查器會取得完整的類別名稱並顯示它
Serial version
。
概括
現在我們知道它是什麼
SerialVersionUID
以及為什麼在類別中聲明它很重要
Serializable
,是時候回顧一下與 Java SerialVersionUID 相關的一些重要事實了。
SerialVersionUID
用於指示序列化資料的版本。
- 當我們不在
SerialVersionUID
類別中聲明時,Java運行時會為我們做這件事,但是這個過程對類別的許多元資料敏感,包括欄位數量、欄位類型、欄位存取修飾符、類別中實作的介面等。您可以在Oracle 的序列化文件中找到確切的資訊。
- 建議將 SerialVersionUID 宣告為 private static final long 變數以避免預設機制。如果您忘記了這一點,某些 IDE(例如Eclipse)也會發出警告,例如:「Serialized 類別 Customer 未聲明 long 類型的靜態最終 SerialVersionUID 欄位。」。儘管您可以透過前往「視窗」>「首選項」>「Java」>「編譯器」>「錯誤/警告」>「潛在程式設計問題」來停用此警告,但我建議不要這樣做。只有不需要資料恢復的時候我才可以大意。這是這個錯誤在 Eclipse IDE 中的樣子,您所需要做的就是快速做出第一個決定。
- 您也可以使用 JDK 中的 Serialver 實用程式為 Java 中的類別產生串行版本。該實用程式還有一個 GUI,在傳遞 - 參數時啟用
show
。
- 序列化的最佳實踐是顯式聲明
SerialVersionUID
, 以避免反序列化出現任何問題,特別是當您使用依賴於序列化資料的客戶端-伺服器應用程式(例如 RMI)時。
這都是關於
SerialVersionUID
Java 的。現在我們知道為什麼在課堂上正確聲明很重要
SerialVersionUID
。您可以感謝 IDE 的提醒,這可能會破壞您的類別的反序列化。如果您想了解有關序列化和相關概念的更多信息,您還可以查看這些精彩的文章。
原文
在這裡
GO TO FULL VERSION