序列化將物件狀態轉換為位元組串流,便於持久化儲存(檔案、資料庫)或網路傳輸(RMI、HTTP)。反序列化則是將位元組串流重建為物件。Java 透過 Serializable 標記介面與 ObjectOutputStream/ObjectInputStream 實現此機制,設計極為簡潔。
| 類別/介面 | 角色 | 關鍵方法 |
|---|---|---|
Serializable | 標記介面,無方法 | — |
ObjectOutputStream | 序列化輸出 | writeObject(Object) |
ObjectInputStream | 反序列化輸入 | readObject() |
Externalizable | 自訂序列化協議 | writeExternal/readExternal |
public class Serial implements Serializable {
private static final long serialVersionUID = 1L; // 強烈建議顯式宣告
int companyId;
String companyAddr;
boolean companyFlag;
// 建構子、getter/setter、toString()...
}
// 序列化寫入檔案
try (FileOutputStream fos = new FileOutputStream("data.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
Serial obj = new Serial(752, "Dayer Street #5", false);
oos.writeObject(obj);
}
// 反序列化讀取檔案
try (FileInputStream fis = new FileInputStream("data.ser");
ObjectInputStream ois = new ObjectInputStream(fis)) {
Serial obj = (Serial) ois.readObject();
System.out.println(obj); // DATA: 752 Dayer Street #5 false
}
serialVersionUID 版本控制InvalidClassExceptionprivate static final long serialVersionUID = 1L; 可控制相容性transient 關鍵字private transient String password; // 不序列化敏感資料
private transient Logger logger; // 非可序列化物件
反序列化時 transient 欄位預設為 null/0/false,需在 readObject() 中手動恢復。
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject(); // 執行預設序列化
out.writeObject(encrypt(password)); // 加密後寫入密碼
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
this.password = decrypt((String) in.readObject());
}
序列化會破壞單例(每次反序列化產生新實例)。解決:實作 readResolve() 回傳單例實例。
private Object readResolve() {
return INSTANCE; // 回傳唯一實例
}
Externalizable 完全掌控二進位格式ByteArrayOutputStream 記憶體操作避免磁碟 I/OObjectOutputStream.reset() 避免記憶體洩漏反序列化不受信資料可導致遠端程式碼執行(RCE)。防禦措施:
ObjectInputFilter 白名單類別serialize -> deserialize 實現物件圖完整複製Java 序列化雖然簡單易用,但效能一般、版本演進複雜、安全風險高。現代架構建議:內部通訊用 Protobuf/Avro,對外 API 用 JSON,僅在相容舊系統時使用原生序列化。掌握 serialVersionUID、transient、自訂 readObject/writeObject、readResolve 等進階機制,才能駕馭複雜序列化場景。