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

Java final 關鍵字深度解析:數據、方法、類、參數的不可變語義

     編輯:Java 相關知識

核心語義:final =「不可變」

final 表達「這部分不允許被修改」,動機有二:效能優化(編譯期常量折疊、JIT 內聯)與 設計意圖(防止繼承/覆蓋、保證線程安全不可變對象)。

一、final 數據:編譯期常量 vs 運行期常量

類型初始化時機可變性典型用法
編譯期常量類加載階段永遠不可變static final int MAX = 100;、基本類型 + 字面量
運行期常量構造器/實例化時引用不可變,對象內容可變final List list = new ArrayList();、final int id = random.nextInt();

代碼演示

public class FinalTest {
    private final String compileConst = "chenssy";           // 編譯期常量
    private final String runtimeConst;                       // 構造器初始化
    private final int randomVal = new Random().nextInt(50);  // 運行期確定
    public final Person personRef = new Person("chen_ssy");  // 引用不可變

    public FinalTest(String runtimeConst) { this.runtimeConst = runtimeConst; }

    public static void main(String[] args) {
        FinalTest t1 = new FinalTest("cm");
        FinalTest t2 = new FinalTest("zj");
        System.out.println(t1); // compileConst=chenssy, runtimeConst=cm, randomVal=34, personRef=chen_ssy
        System.out.println(t2); // compileConst=chenssy, runtimeConst=zj, randomVal=46, personRef=chen_ssy

        t2.personRef.setName("chenssy"); // 修改引用對象內部狀態 ✅ 允許
        System.out.println(t2); // personRef=chenssy
    }
}

關鍵點: final 修飾引用類型時,引用不可變,但指向對象的內部狀態可變。

二、final 方法:鎖定實現與效能考量

  • 防覆蓋: 子類不可覆蓋 final 方法,鎖定演算法實現(如模板方法模式中的關鍵步驟)。
  • 效能: 早期 JVM 會將 final 方法內聯(inline),消除方法調用開銷。現代 JIT 對熱點方法自動內聯,final 提示作用減弱,但語義仍重要。

三、final 類:不可繼承的終極形態

  • 標記為 final class 表示不設計繼承,典型如 String、Integer、Math。
  • 類 final → 所有方法隱式 final(無法被覆蓋),成員變量可選擇 final 或非 final。

四、final 參數:保護參數不被竄改

public void process(final int value) {
    // value = 10; // 編譯錯誤
}

public void modify(final Person p) {
    // p = new Person(); // 編譯錯誤:引用不可變
    p.setName("new");    // ✅ 允許:修改對象內部狀態
}

匿名內部類場景: 外部方法參數若需被匿名內部類使用,必須聲明 final(Java 8+ 隱式 final),確保參數生命週期覆蓋內部類實例,避免引用不一致。

五、final + static = 全局常量

public static final double PI = 3.1415926;
public static final String CONFIG_PATH = "/etc/app/config";
  • 類加載時初始化,內存唯一拷貝,通過 ClassName.CONSTANT 訪問。
  • 命名慣例:全大寫 + 下劃線分隔。

總結表

修飾目標不可變內容典型場景
基本類型變量數值常量定義
引用類型變量引用地址集合引用、依賴注入
方法方法體實現模板方法、工具方法
類繼承關係不可變對象、工具類
參數參數引用/值匿名內部類、防誤賦值
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved