序列化:將對象轉換為字節序列,包含對象數據與類型信息,可寫入文件、數據庫或網絡傳輸。
反序列化:將字節序列恢復為原始 Java 對象。
實現 Serializable 接口即可賦予類序列化能力,常用於緩存(如 Redis)、RPC 遠程調用、Session 持久化等場景。
transient 修飾的成員變量不參與序列化過程,反序列化時該字段將被設置為默認值(引用類型為 null,基本類型為 0/false)。
HashMap.modCount(結構修改計數器),反序列化後重置為 0 不影響正確性class Rectangle implements Serializable {
private static final long serialVersionUID = 1L;
private Integer width;
private Integer height;
private transient Integer area; // 派生字段,不序列化
public Rectangle(Integer width, Integer height) {
this.width = width;
this.height = height;
this.area = width * height;
}
public void recalcArea() { this.area = this.width * this.height; }
@Override public String toString() {
return "width: " + width + "\nheight: " + height + "\narea: " + area;
}
}
// 測試
Rectangle rect = new Rectangle(3, 4);
System.out.println("1. 原始對象\n" + rect);
// 輸出: width: 3, height: 4, area: 12
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("rect.ser"));
oos.writeObject(rect);
oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("rect.ser"));
Rectangle rect2 = (Rectangle) ois.readObject();
System.out.println("2. 反序列化後\n" + rect2);
// 輸出: width: 3, height: 4, area: null ← transient 字段為 null
rect2.recalcArea(); // 手動恢復派生字段
System.out.println("3. 恢復後\n" + rect2);
// 輸出: width: 3, height: 4, area: 12
/**
* 結構修改次數:put、remove、rehash 時自增
* 用於實現 fail-fast 迭代器
* 反序列化後重置為 0 完全無影響
*/
transient int modCount;
recalcArea()writeObject/readObject 可實現更精細控制(如加密敏感字段)NotSerializableExceptiontransient 是 Java 提供的序列化「開關」,核心價值在於數據安全與存儲優化。合理使用可避免敏感信息洩露、減小序列化體積、解決非可序列化對象引用問題。實際開發中,建議對所有實現 Serializable 的類審視每個字段是否需要持久化,默認添加 transient,按需保留。