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

Java 關鍵字深度解析:final 與 transient 的核心機制與實戰陷阱

     編輯:Java 綜合教學

final:不只是「不可變」

1. final 修飾基本類型變量

  • 編譯期常量(static final + 字面量/常量表達式)進入常量池,調用處直接內聯,性能最優。
  • 運行期初始化的 final(空白 final)必須在構造器/實例初始化塊中賦值,且僅能賦值一次。
public class FinalDemo {
    private final int instanceConst = 10;           // 實例常量
    private static final int CLASS_CONST = 20;      // 類常量
    private final int blankFinal;                   // 空白 final

    public FinalDemo(int val) {
        this.blankFinal = val; // 必須在構造器初始化
    }
}

2. final 修飾引用類型變量

引用不可變,對象內容可變:

final List<String> list = new ArrayList<>();
list.add("hello"); // ✅ 合法:修改對象內部狀態
// list = new ArrayList<>(); // ❌ 編譯錯誤:嘗試改變引用指向

3. final 修飾方法與類

  • 方法:禁止子類重寫,鎖定行為。JDK 1.5+ JIT 內聯優化使性能優勢可忽略,核心價值在「設計意圖」。
  • 類:禁止被繼承(如 String, Integer),保證不可變性與安全性。

4. final 修飾方法參數

參數在方法體內不可重新賦值,常用於匿名內部類/Lambda 捕獲變量(需 effective final)。

transient:序列化的「隱身術」

核心規則

  1. 僅修飾實例變量,標記該字段不參與默認序列化。
  2. static 變量本屬於類,不參與序列化,transient 無效果。
  3. 反序列化時,transient 字段會被賦予默認值(null/0/false)。

代碼驗證

public class TransientDemo implements Serializable {
    private String username = "admin";
    private transient String password = "123456"; // 不序列化
    private static final String VERSION = "1.0";  // static 不序列化

    public static void main(String[] args) throws Exception {
        TransientDemo obj = new TransientDemo();
        // 序列化
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.ser"))) {
            oos.writeObject(obj);
        }
        // 反序列化
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.ser"))) {
            TransientDemo restored = (TransientDemo) ois.readObject();
            System.out.println("username: " + restored.username); // admin
            System.out.println("password: " + restored.password); // null ← transient 生效
            System.out.println("VERSION: " + restored.VERSION);   // 1.0 ← static 屬於類
        }
    }
}

Externalizable:完全掌控序列化協議

實現 Externalizable 後,默認序列化機制完全失效(transient 也無效),必須手動實現 writeExternal/readExternal:

public class FullControl implements Externalizable {
    private transient String secret = "hidden"; // transient 此處無效!

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject("encrypted_" + secret); // 手動決定寫什麼
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.secret = ((String) in.readObject()).replace("encrypted_", "");
    }
}

總結對比表

關鍵字作用目標核心語義典型場景
final變量/方法/類/參數不可變/不可重寫/不可繼承常量定義、不可變對象、模板方法、線程安全共享
transient實例變量跳過默認序列化敏感字段(密碼)、衍生字段、非序列化第三方對象引用
Externalizable類完全自定義序列化邏輯特殊格式持久化、加密序列化、版本兼容控制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved