為什麼要顯式聲明 serialVersionUID?不聲明會怎樣?聲明後修改類結構會發生什麼?
未顯式聲明時,JVM 根據類結構(字段、方法、接口等)計算哈希值作為 serialVersionUID。任何結構變更都會導致值改變。
public class User implements Serializable {
// 顯式聲明,鎖定版本號
private static final long serialVersionUID = 1L;
private String name;
private int age;
// 新增字段不影響反序列化
private String email;
}
| 場景 | 無 serialVersionUID | 有 serialVersionUID |
|---|---|---|
| 類結構未變 | 正常反序列化 | 正常反序列化 |
| 增加字段 | InvalidClassException | 正常,新字段賦默認值 |
| 刪除字段 | InvalidClassException | 正常,舊數據忽略 |
| 修改字段類型 | InvalidClassException | 仍拋出異常 (類型不兼容) |
private static final long serialVersionUID = 1L;反序列化時,ObjectInputStream.readClassDescriptor() 讀取流中的 UID,與本地類 UID 比對。匹配則繼續,不匹配拋 InvalidClassException。UID 相同但結構不兼容時,在字段映射階段拋出異常。
參考詳細解析:Java 序列化版本控制詳解