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

J2SE 序列化深度解析:當序列化遭遇繼承關係

     編輯:Java 相關知識

情境一:父類實作 Serializable → 子類自動可序列化


class SuperC implements Serializable {
    int superValue;
    public SuperC(int v) { superValue = v; }
    public String toString() { return "superValue: " + superValue; }
}

class SubC extends SuperC {
    int subValue;
    public SubC(int sv, int v) { super(sv); subValue = v; }
    public String toString() { return super.toString() + " sub: " + subValue; }
}

// 測試
SubC obj = new SubC(100, 200);
// 序列化 → 反序列化
// 輸出:superValue: 100 sub: 200

子類無需額外代碼即可完整序列化/反序列化父類欄位。

情境二:父類未實作 Serializable → 子類想序列化(棘手)

JavaDocs 規定兩個必要條件:

  1. 父類必須有 **可訪問的無參建構子**
  2. 子類必須 **手動序列化/反序列化父類欄位**

失敗案例:父類無無參建構子


public abstract class SuperC {  // 無 Serializable
    int superValue;
    public SuperC(int v) { superValue = v; }  // 唯一建構子有參
    // 缺少無參建構子
}
class SubC extends SuperC implements Serializable { ... }
// 編譯錯誤:Serializable cannot be resolved...

修正版:補無參建構子 + 實作 writeObject/readObject


public abstract class SuperC {
    int superValue;
    public SuperC(int v) { superValue = v; }
    public SuperC() {}  // 關鍵:補上無參建構子
}

class SubC extends SuperC implements Serializable {
    int subValue;
    public SubC(int sv, int v) { super(sv); subValue = v; }

    // 自定義序列化:先預設序列化自身,再手動寫入父類欄位
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeInt(superValue);
    }

    // 自定義反序列化:先預設讀取自身,再手動讀取父類欄位
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        superValue = in.readInt();
    }
}

defaultWriteObject()/defaultReadObject() 處理當前類別非 transient/non-static 欄位,父類欄位需手動讀寫並**順序一致**。

總結對照表

場景處理方式
父類已實作 Serializable子類自動獲得序列化能力,無需額外代碼
父類未實作 Serializable1. 父類加無參建構子 2. 子類實作 writeObject/readObject 手動處理父類欄位

核心原理

  • 序列化機制透過反射檢查類別結構
  • 父類無 `Serializable` 時,其欄位不在預設序列化圖譜中
  • 子類介入序列化流程(`writeObject`/`readObject`)彌補缺口
  • 無參建構子用於反序列化時實例化父類部分狀態
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved