Java 序列化將物件狀態轉為位元組流,便於寫入檔案、網路傳輸或資料庫存儲。實作 java.io.Serializable 介面(標記介面,無方法)即可賦予類別序列化能力。反序列化則將位元組流還原為物件。
package test;
import java.io.*;
public class Test implements Serializable {
int i = 0;
// transient 關鍵字:標記此欄位不參與序列化
transient int j = 0;
public static void main(String[] args) {
Test test = new Test();
test.i = 3;
test.j = 7;
System.out.println("序列化前: i=" + test.i + ", j=" + test.j);
// --- 序列化(寫入檔案) ---
try (FileOutputStream fos = new FileOutputStream("c:\\test.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(test);
System.out.println("物件已寫入檔案");
} catch (Exception ex) {
ex.printStackTrace();
}
// --- 反序列化(讀取檔案) ---
try (FileInputStream fis = new FileInputStream("c:\\test.obj");
ObjectInputStream ois = new ObjectInputStream(fis)) {
Test test1 = (Test) ois.readObject();
System.out.println("反序列化後: i=" + test1.i + ", j=" + test1.j);
// 輸出: i=3, j=0 (j 為預設值 0,因未序列化)
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
| 概念 | 說明 |
|---|---|
implements Serializable | 宣告類別可序列化,JVM 自動處理預設序列化邏輯。 |
transient | 修飾實例變數,序列化時跳過該欄位。反序列化後該欄位為類型預設值(int=0, 物件=null)。適用於敏感資料(密碼)、衍生欄位、非序列化物件引用。 |
ObjectOutputStream | 高層流,writeObject() 將物件圖(含引用鏈)寫入底層輸出流。 |
ObjectInputStream | 對應輸入流,readObject() 還原物件圖,需強制轉型。 |
| try-with-resources | JDK 7+ 語法,自動關閉流,避免資源洩漏(範例已採用)。 |
private static final long serialVersionUID = 1L;,確保版本演進時反序列化相容性。private void writeObject(ObjectOutputStream) 和 private void readObject(ObjectInputStream) 可控制複雜邏輯(如加密、補充瞬態欄位)。