首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 序列化與反序列化完整指南:serialVersionUID 核心作用

     編輯:Java 相關知識

基本概念

  • 序列化:物件 → 位元組序列(持久化到磁碟/網路傳輸)。
  • 反序列化:位元組序列 → 物件(還原狀態)。

核心 API:ObjectOutputStream.writeObject() / ObjectInputStream.readObject()。

實作範例

class Person implements Serializable {
    private static final long serialVersionUID = -5809782578272943999L;
    int age; String name, sex; /* getter/setter */
}

public class SerializeDemo {
    static void serialize() throws IOException {
        Person p = new Person(); p.setAge(25); p.setName("gacl"); p.setSex("男");
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/Person.txt"))) {
            oos.writeObject(p);
        }
    }
    static Person deserialize() throws IOException, ClassNotFoundException {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/Person.txt"))) {
            return (Person) ois.readObject();
        }
    }
}

serialVersionUID 核心作用

序列化版本號,用於驗證序列化資料與當前類別定義相容性。

未顯式宣告的風險

  • 編譯器依據類別結構自動生成,任何修改(增欄位、改方法)都會導致 UID 變更。
  • 反序列化時 UID 不匹配 → 拋 InvalidClassException。

顯式宣告的兩大用途

  1. 相容演進:固定 UID,允許新增欄位/方法,舊資料仍可反序列化(新欄位預設值)。
  2. 強制不相容:故意修改 UID,阻止舊資料載入(安全需求)。

實測:固定 UID 實現向前相容

// v1
class Customer implements Serializable {
    static final long serialVersionUID = -5182532647273106745L;
    String name; int age;
}
// 序列化存檔

// v2 新增 sex 欄位
class Customer implements Serializable {
    static final long serialVersionUID = -5182532647273106745L; // 同 UID
    String name; int age; String sex; // 新欄位
}
// 反序列化成功,sex 為 null

serialVersionUID 取值建議

  • 使用 IDE 自動生成(基於類別簽名雜湊),確保唯一性。
  • 專案初期即宣告,避免後續忘記導致相容性中斷。
  • 不可變類別可省略(但建議保留)。

Externalizable 進階控制

實作 Externalizable 需自行實作 writeExternal/readExternal,完全掌控序列化格式與版本邏輯,適合極致效能或特殊協議場景。

總結

serialVersionUID 是序列化相容性的守門員。務必顯式宣告,並隨著類別演進謹慎決定是否變更。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved