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

Java 序列化與克隆深度解析:機制、實現與版本兼容最佳實踐

     編輯:J2EE

一、 序列化:物件跨越時空的通用協議

核心概念

  • 序列化:將物件狀態轉換為位元組序列,寫入輸出流(檔案/網路/記憶體)。
  • 反序列化:從輸入流讀取位元組序列,重構物件圖。
  • 遠端通訊雙方透過序列化/反序列化實現物件級數據交換,屏蔽底層協議細節。

主要用途

  1. 持久化物件狀態至磁碟(應用重啟自動恢復)。
  2. 網路傳輸物件(RMI、分散式緩存、訊息隊列載體)。

JDK 核心 API

  • ObjectOutputStream.writeObject(Object):序列化寫入。
  • ObjectInputStream.readObject():反序列化讀取。
  • 只有實現 Serializable(標記介面)或 Externalizable(完全自控序列化行為)的類才可序列化。

標準流程範例

// 序列化
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("obj.dat"));
out.writeObject("Hello");
out.writeObject(new Date());
out.writeObject(new Customer("Amy", 24));
out.writeInt(123);
out.close();

// 反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("obj.dat"));
System.out.println((String) in.readObject());
System.out.println((Date) in.readObject());
System.out.println((Customer) in.readObject());
System.out.println(in.readInt());
in.close();

輸出結果

Hello
Sat Sep 26 22:02:21 CST 2010
name=Amy, age=24
123

serialVersionUID:版本兼容的基石

序列化執行期會檢查 serialVersionUID 一致性,不一致拋出 InvalidClassException。兩種生成策略:

  • 顯式指定常數:private static final long serialVersionUID = 1L; —— 簡單、穩定,手動控制兼容性。
  • 工具生成哈希:基於類名、介面、成員結構生成 64 位雜湊值 —— 精準反映結構變更,但需工具輔助。

最佳實踐:永遠顯式宣告 serialVersionUID,避免編譯器隱式生成導致跨 JVM/版本不兼容。

二、 克隆:物件複製的兩種語義

淺複製

  • 基本型別直接複製值;引用型別複製引用地址(指向同一物件)。
  • 實現:implements Cloneable + 覆寫 clone() 呼叫 super.clone()。

深複製

  • 引用型別所指物件也遞歸複製,形成完全獨立的物件圖。
  • 兩種實現路徑:
    1. 手工遞歸:clone() 中對引用欄位逐一 clone()。
    2. 序列化+反序列化:將物件寫入 ByteArrayOutputStream,再讀回,自動獲得深複製(要求物件圖全可序列化)。

選型建議

場景推薦方案
簡單不可變物件 / 僅基本型別欄位淺複製
複雜可變物件圖、需完全隔離副本深複製(序列化法最省碼)
跨進程/跨機器傳輸序列化(標準協議)
高頻、大對象、效能敏感考慮 Protobuf/Kryo 等高效二進制方案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved