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

Java 序列化核心知識體系:從基礎機制到實戰避坑指南

     編輯:Java 綜合教學

什麼是序列化?

序列化是將對象狀態轉換為字節流的過程,用於網絡傳輸或持久化存儲;反序列化則是將字節流還原為對象的逆向操作。

主要應用場景

  1. 將內存對象持久化到文件或數據庫
  2. 分布式系統間的網絡對象傳輸(RPC、Session 同步等)

兩種實現方式

1. 實現 Serializable 接口(標準模式)

  • 標記接口,無需實現任何方法,使用最簡單
  • 默認序列化所有非 transient、非 static 字段
  • 筆者從業兩年 Web 開發均採用此方式

2. 實現 Externalizable 接口(完全控制模式)

  • Serializable 子接口,需實現 writeExternal() / readExternal()
  • 可精確控制序列化字段、順序與邏輯,性能更優但開發成本高

Serializable 實戰七大注意點

#規則說明
1 serialVersionUID 必須一致 反序列化三條件:類路徑一致、功能代碼一致、序列化 ID 一致。建議顯式聲明 private static final long serialVersionUID = 1L; 避免跨版本兼容問題
2 引用對象級聯序列化 對象 A 引用 B,A 實現序列化則 B 自動序列化。若 B 未實現 Serializable 將拋出 NotSerializableException
3 父類序列化傳遞性 父類實現序列化 → 子類自動序列化;子類序列化 → 父類不序列化,反序列化時調用父類無參構造器初始化
4 transient 字段跳過序列化 標記為 transient 的字段視為臨時數據,序列化時忽略,反序列化後為默認值(null/0/false)
5 static 字段不屬於對象狀態 static 代表類屬性,不參與對象序列化
6 敏感字段需自定義加密序列化 即使 private 也可被反序列化讀取。須重寫 writeObject() / readObject() 實現加密/解密邏輯。虛擬機優先調用自定義方法,否則走 defaultWriteObject/defaultReadObject
7 同一對象重複寫入僅存儲引用 同一對象多次 writeObject,文件大小不翻倍,僅增加引用控制信息

自定義序列化代碼範本

private void writeObject(ObjectOutputStream out) throws IOException {
    // 加密敏感字段
    out.defaultWriteObject(); // 先執行默認序列化
    // 或手動控制每個字段寫入順序
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject(); // 先執行默認反序列化
    // 解密敏感字段
}

最佳實踐建議

  • 顯式聲明 serialVersionUID,避免編譯器自動生成導致版本不兼容
  • 謹慎使用 transient,明確業務語義上的「臨時數據」
  • 敏感數據(密鑰、密碼、身份證號)必須加密序列化
  • 大對象圖序列化注意性能,考慮分批或採用更高效協議(Protobuf、Kryo)
  • 跨語言場景避免 Java 原生序列化,改用 JSON、Protocol Buffers 等通用格式
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved