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

Java transient 關鍵字深度解析:序列化控制與最佳實踐

     編輯:Java 綜合教學

Java transient 關鍵字:讓敏感字段「隱身」於序列化之外

前置知識:對象序列化與反序列化

序列化:將對象轉換為字節序列,包含對象數據與類型信息,可寫入文件、數據庫或網絡傳輸。

反序列化:將字節序列恢復為原始 Java 對象。

實現 Serializable 接口即可賦予類序列化能力,常用於緩存(如 Redis)、RPC 遠程調用、Session 持久化等場景。

transient 關鍵字作用

transient 修飾的成員變量不參與序列化過程,反序列化時該字段將被設置為默認值(引用類型為 null,基本類型為 0/false)。

適用場景

  1. 派生字段:值可由其他字段計算得出(如矩形面積 = 長 × 寬),無需持久化
  2. 敏感數據:密鑰、密碼、Token 等不應寫入磁盤或網絡傳輸
  3. 非線程安全/運行時上下文:如 HashMap.modCount(結構修改計數器),反序列化後重置為 0 不影響正確性
  4. 節省存儲空間:大對象或可重建對象(如線程池、連接池、輸入流)

實戰案例:矩形類

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

源碼級案例:HashMap.modCount

/**
 * 結構修改次數:put、remove、rehash 時自增
 * 用於實現 fail-fast 迭代器
 * 反序列化後重置為 0 完全無影響
 */
transient int modCount;

注意事項與最佳實踐

  • static 字段不受 transient 影響:static 屬於類不屬於實例,本身不參與序列化
  • 反序列化後需手動初始化:如案例中調用 recalcArea()
  • 配合自定義序列化:實現 writeObject/readObject 可實現更精細控制(如加密敏感字段)
  • 不可序列化對象必須標記 transient:否則拋出 NotSerializableException

總結

transient 是 Java 提供的序列化「開關」,核心價值在於數據安全與存儲優化。合理使用可避免敏感信息洩露、減小序列化體積、解決非可序列化對象引用問題。實際開發中,建議對所有實現 Serializable 的類審視每個字段是否需要持久化,默認添加 transient,按需保留。

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