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

Java 核心接口深度解析:java.io.Serializable

     編輯:Java 相關知識

Serializable 接口定位與核心契約

java.io.Serializable 是一個標記介面——無任何方法與欄位,唯一語意是「宣告實作此介面的類允許被序列化」。未實作該介面的類,其狀態無法被序列化或反序列化。所有子類若父類實作了 Serializable,預設也是可序列化的。

非序列化父類的子類序列化規則

允許非序列化父類的子類實作 Serializable,但子類必須負責保存/恢復父類的 public、protected 及可訪問的 package-private 欄位。前提是父類擁有 public 或 protected 的無參建構子,否則反序列化時會拋出 InvalidClassException(運行時檢測)。

反序列化初始化流程

  • 可序列化欄位:從物件流自動恢復。
  • 非序列化父類欄位:呼叫父類無參建構子初始化。
  • 子類必須能訪問父類無參建構子(public/protected)。

特殊處理:writeObject / readObject

若類需自定序列化邏輯,須實作以下 private 方法(非介面方法,由反射調用):

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
  • writeObject:寫入物件狀態,可呼叫 out.defaultWriteObject() 觸發預設機制(非 static、非 transient 欄位)。
  • readObject:讀取並恢復狀態,可呼叫 in.defaultReadObject() 觸發預設恢復。新增欄位時相容性由流中資訊自動處理。

常見陷阱與最佳實踐

  1. NotSerializableException:物件圖中出現未實作 Serializable 的物件,異常會指明具體類別。
  2. serialVersionUID:強烈建議顯式宣告 private static final long serialVersionUID,避免跨版本反序列化失敗。
  3. transient:標記不需序列化的欄位(如緩存、執行緒、資料庫連線)。
  4. 繼承鏈:只有實作 Serializable 的最頂層類負責整條鏈的序列化協調;中間若有非序列化類,需符合上述無參建構子要求。

總結

Serializable 雖是標記介面,但其背後涉及物件圖遍歷、版本演進、父類協作等機制。掌握 writeObject/readObject、serialVersionUID、transient 等細節,是構建健壯分散式/持久化 Java 系統的基本功。

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