class Test1 {
final double PI = 3.14; // 聲明即初始化
public Test1() { /* PI = 3.14; */ } // 若構造器再賦值會報錯
void test() { System.out.println("PI is: " + PI); }
public static void main(String[] args) { new Test1().test(); }
}
class Test1 {
final double PI; // 未初始化
Test1() { PI = 3.14; } // 構造器賦值,否則編譯錯誤
void test() { System.out.println("PI is: " + PI); }
}
class Test1 {
static final double PI;
static { PI = 3.14; } // 靜態初始化塊
void test() { System.out.println("PI is: " + PI); }
}
class Test {
static final double PI = 3.14;
final void test() { System.out.println("PI is: " + PI); }
}
class Test1 extends Test {
public static void main(String[] args) { new Test1().test(); }
}
// 輸出: PI is: 3.14
// 子類不可覆寫 test(),嘗試會編譯失敗
final class Test1 {
static final double PI = 3.14;
final void test() { System.out.println("PI is: " + PI); }
public static void main(String[] args) { new Test1().test(); }
}
// 任何類嘗試 extends Test1 都會編譯報錯
String 引用永遠指向 String 對象,防止子類破壞行為final 類方法,無需虛表查找public final class ImmutablePoint { // 1. 類 final
private final int x, y; // 2. 字段 final + private
public ImmutablePoint(int x, int y) { this.x = x; this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
// 3. 無 setter,所有「修改」返回新實例
public ImmutablePoint translate(int dx, int dy) {
return new ImmutablePoint(x + dx, y + dy);
}
// 4. 防禦性拷貝(若持有可變對象)
// private final List tags;
// public ImmutablePoint(List tags) { this.tags = new ArrayList<>(tags); }
}
| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
final List list = new ArrayList(); list = null; | 嘗試改變引用 | 只修改內容:list.clear() |
final int x; // 類字段無初始化 | 空白 final 未在構造器賦值 | 構造器中 this.x = 0; |
static final int x; // 靜態字段無初始化 | 靜態空白 final 未在靜態塊賦值 | 靜態塊 static { x = 0; } |
| 匿名內部類使用非 final 局部變量 | 編譯錯誤 | 加 final 或改為 effectively final |
final 是 Java 表達「不可變意圖」的核心工具。從基本類型常量到不可變類設計,掌握其初始化規則、引用語義與設計哲學,能寫出更安全、更清晰、更易優化的代碼。