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

Java 序列化深度解析:從基本用法到原理、版本控制與替代方案

     編輯:Java 綜合教學

Java 序列化深度解析:從基本用法到原理、版本控制與替代方案

本文為「計算機程序的思維邏輯」系列第 62 節,系統講解 Java 標準序列化機制,涵蓋 Serializable、ObjectOutputStream/ObjectInputStream、自定義序列化、循環引用處理、版本號、Externalizable 以及與 JSON/ProtoBuf 的對比。

基本用法

只需讓類實現 java.io.Serializable 標記接口,即可使用 ObjectOutputStream.writeObject() 與 ObjectInputStream.readObject() 進行對象持久化或網絡傳輸。

public class Student implements Serializable {
    String name; int age; double score;
    // 構造器、getter/setter...
}

// 寫入
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("students.dat"));
out.writeObject(studentList);
out.close();

// 讀取
ObjectInputStream in = new ObjectInputStream(new FileInputStream("students.dat"));
List list = (List) in.readObject();
in.close();

集合類(ArrayList、HashMap 等)與常見類(String、Date)均已實現 Serializable,可直接整體讀寫。

複雜對象圖自動處理

  • 共享引用:A、B 同時引用 C,序列化後反序列化仍指向同一 C 實例。
  • 循環引用:Parent ↔ Child 相互引用,序列化機制通過對象編號(handle)正確重建圖結構。

底層邏輯:ObjectOutputStream 維護「已寫對象表」,遇到重複對象僅寫入引用編號;ObjectInputStream 反序列化時同樣維護表,確保圖結構一致性。

自定義序列化

當默認序列化不符合邏輯結構(如 LinkedList 的節點指針屬於實現細節)時,可採用:

  1. transient 關鍵字:跳過該字段的默認序列化。
  2. 實現 private void writeObject(ObjectOutputStream s) 與 private void readObject(ObjectInputStream s):完全掌控讀寫流程,必須調用 s.defaultWriteObject()/s.defaultReadObject() 處理非 transient 字段及元數據。
// LinkedList 示例
private void writeObject(ObjectOutputStream s) throws IOException {
    s.defaultWriteObject(); // 必須
    s.writeInt(size);
    for (Node x = first; x != null; x = x.next) s.writeObject(x.item);
}

序列化版本控制

建議顯式聲明 private static final long serialVersionUID = 1L;,避免 JVM 自動生成導致跨版本反序列化失敗(InvalidClassException)。兼容性規則:

  • 字段刪除:流中有、類中無 → 忽略。
  • 字段新增:類中有、流中無 → 賦默認值。
  • 字段類型變更 → 拋出異常。

進階機制

  • Externalizable:完全手動控制,需實現 writeExternal/readExternal,反序列化先調無參構造器,性能優於反射機制。
  • readResolve:單例模式反序列化保護,返回唯一實例。
  • writeReplace:序列化代理模式,返回替代對象。

優缺點與替代方案

優點缺點
使用簡單、自動處理引用/循環、支援版本演進Java 私有二進制格式、體積大、反射性能低、不可跨語言

跨語言、高性能場景建議採用:JSON(可讀性好)、ProtoBuf/Thrift/MessagePack(二進制高效)。

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