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

Java 序列化深度解析:Serializable 與 Externalizable 完整指南

     編輯:Java 相關知識

序列化核心作用

將對象狀態(成員變量)轉換為字節序列,用於:文件持久化、網絡傳輸、RMI 遠程調用。反序列化則還原對象。

兩大實現接口對比

特性SerializableExternalizable
接口方法標記接口,無方法writeExternal/readExternal (public)
默認行為自動序列化非 transient/static 字段完全手動控制,無默認行為
構造函數無要求必須有公共無參構造器
安全性較高public 方法可被惡意調用
性能反射開銷大手動編碼通常更快
版本控制serialVersionUID自行管理版本邏輯

Serializable 進階機制

1. transient 與 static 跳過

class Box implements Serializable {
    private static int width;   // static 不序列化
    private transient int height; // transient 不序列化
    private String name;        // 正常序列化
}

反序列化時,static 字段取類當前值,transient 取默認值(int=0)。

2. 自定義序列化:writeObject/readObject

private void writeObject(ObjectOutputStream out) throws IOException {
    out.defaultWriteObject(); // 先執行默認邏輯
    out.writeInt(height);     // 手動寫入 transient
    out.writeInt(width);      // 手動寫入 static
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    height = in.readInt();    // 順序必須與寫入一致
    width = in.readInt();
}

3. 不可序列化對象處理

Thread、Socket 等持有系統資源的對象不可序列化,強制實現會拋 NotSerializableException。解決:標記為 transient 或排除在外。

Externalizable 完全控制示例

class Box implements Externalizable {
    private int width, height;
    private String name;
    public Box() {} // 必須有無參構造器
    public Box(String n, int w, int h) { name=n; width=w; height=h; }
    
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeInt(width);
        out.writeInt(height);
    }
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        width = in.readInt();
        height = in.readInt();
    }
}

ObjectOutputStream/InputStream 關鍵方法

  • writeObject/readObject:核心對象讀寫
  • writeInt/readInt 等:基本類型讀寫
  • defaultWriteObject/defaultReadObject:在自定義方法中調用默認邏輯

總結

優先使用 Serializable + serialVersionUID + 必要時 writeObject/readObject;極致性能或特殊格式需求時考慮 Externalizable。注意 transient、static 語義差異,妥善處理不可序列化字段。

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