serialVersionUID 是 Java 序列化機制中的**版本控制號**。當一個類實作 Serializable 介面時,JVM 會根據類的結構(類名、介面、成員、方法等)自動計算一個 64 位的 hash 值作為預設的 serialVersionUID。但在實際開發中,**強烈建議顯式宣告**。
序列化的本質是將物件狀態轉為位元組流持久化(寫入檔案、網路傳輸)。反序列化時,JVM 會比較「流中的 serialVersionUID」與「當前類的 serialVersionUID」:
InvalidClassException,反序列化失敗private static final long serialVersionUID = 1L;
優點:簡單、可控、跨平台一致。只要類的「語義兼容」就不變更此值。
private static final long serialVersionUID = -7583921456789012345L;
Eclipse/IntelliJ 可自動計算。缺點:類結構微調(如新增 private 方法)就會導致值變更,造成不必要的序列化中斷。
Window → Preferences → Java → Compiler → Errors/Warnings → Potential programming problems → Serializable class without serialVersionUID 設為 Ignore/Warning/ErrorSettings → Editor → Inspections → Java → Serialization → Serializable class without 'serialVersionUID'游標置於類名上 → Alt+Enter (IntelliJ) 或 Ctrl+1 (Eclipse) → 選擇「Add default serial version ID」或「Generate serialVersionUID」。
// v1
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
}
// v2 新增 age
class User implements Serializable {
private static final long serialVersionUID = 1L; // 保持不變
private String name;
private int age; // 反序列化 v1 資料時,age 自動為 0
}
✅ 兼容成功。
若將 name 改為 fullName,或刪除 name,舊資料反序列化會導致資料遺失或型別不匹配。**此時必須升級 serialVersionUID**(如改為 2L),並提供資料遷移邏輯。
private static final long serialVersionUID = 1L;對於長期演進的系統,建議採用 Protobuf、Avro、JSON 等跨語言、支援 Schema 演進的序列化協議,而非依賴 Java 原生序列化。