Java 物件序列化能將實作 Serializable 介面的物件轉換為位元組序列,隨後可從位元組完全重建物件。此機制甚至跨平台運作(Windows 序列化 → Unix 反序列化),自動處理位元組序、資料表示等底層差異。
public interface Serializable {
// 標記介面:無任何方法、無任何欄位
// 僅作為語義標識:實作此介面的類允許被序列化
}
transient 與 static 欄位不參與序列化// 序列化寫入
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.dat"));
oos.writeObject(myObject);
oos.close();
// 反序列化讀取
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
MyObject obj = (MyObject) ois.readObject(); // 需向下轉型
ois.close();
序列化不僅保存物件本身,還會遞歸追蹤其引用的所有物件(物件圖),包含陣列、集合內部元素。這點極其強大——手動實作需編寫複雜遍歷邏輯,Java 內建機制自動優化完成。
「當 Bean 在建構工具中被客製化並與其他 Bean 建立連接後,其所有狀態必須可被保存,下次載入時恢復上次狀態。因此 Bean 應實作
java.io.Serializable。」
public class Button implements java.io.Serializable {
// 所有公開屬性自動保存
// 不想保存的欄位加 transient 或 static
private transient String tempCache; // 不序列化
private static final String CONST = "固定值"; // 不序列化
}
private static final long serialVersionUID = 1L;
InvalidClassExceptionprivate void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject(); // 執行預設序列化
// 額外邏輯:加密敏感欄位、壓縮大物件等
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
// 額外邏輯:解密、初始化 transient 欄位等
}
| 方案 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| Java 序列化 | 臨時持久化、RMI、Bean 工具 | 零配置、內建、物件圖自動遍歷 | 效能一般、二進制不透明、版本演進脆弱 |
| JSON (Jackson/Gson) | Web API、配置檔、跨語言 | 可讀、通用、版本容忍度高 | 需依賴庫、不支援物件圖循環引用(需配置) |
| Protobuf/Avro | 高效能 RPC、大數據存儲 | 極致效能、Schema 演進嚴格 | 需定義 Schema、學習曲線陡峭 |
| JDO/Hibernate | 企業級持久化 | 完整 ORM、查詢語言、事務管理 | 重量級、配置複雜 |
實作 Serializable 是 JavaBean 規範的強制要求,支援設計工具的狀態保存與 RMI 通訊。雖然現代架構多採 JSON/資料庫持久化,但理解序列化機制(物件圖遍歷、版本控制、transient 語義)仍是 Java 進階開發者的必修內功。