Java final 關鍵字
final 表示「最終的」,用來限制修改。
final 變數(常數)
final 變數一旦初始化就不能修改:
final int MAX_SIZE = 100;
// MAX_SIZE = 200; // 錯誤!不能修改
final double PI = 3.14159;
final String APP_NAME = "MyApp";
常數命名慣例
// 靜態常數使用 UPPER_SNAKE_CASE
public static final int MAX_VALUE = Integer.MAX_VALUE;
public static final String DEFAULT_NAME = "Unknown";
// 區域 final 變數可以用 camelCase
final int result = calculate();
final 參數
public void process(final int value) {
// value = 10; // 錯誤!不能修改
System.out.println(value);
}
// 確保方法內不會修改參數
public void copyArray(final int[] source, int[] dest) {
// source = new int[10]; // 錯誤!
source[0] = 100; // OK!可以修改內容,不能修改參考
}
final 與參考型別
對於參考型別,final 限制的是參考,不是物件內容:
final int[] arr = {1, 2, 3};
// arr = new int[5]; // 錯誤!不能指向新陣列
arr[0] = 100; // OK!可以修改內容
final StringBuilder sb = new StringBuilder("Hello");
// sb = new StringBuilder(); // 錯誤!
sb.append(" World"); // OK!
final 方法
final 方法不能被子類別覆寫:
public class Parent {
public final void importantMethod() {
System.out.println("這個方法不能被覆寫");
}
}
public class Child extends Parent {
// @Override
// public void importantMethod() { } // 錯誤!
}
final 類別
final 類別不能被繼承:
public final class ImmutableClass {
private final int value;
public ImmutableClass(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
// class SubClass extends ImmutableClass { } // 錯誤!
Java 的 String 就是 final 類別。
blank final
final 變數可以稍後初始化(只能初始化一次):
public class Person {
private final String name; // blank final
public Person(String name) {
this.name = name; // 在建構子中初始化
}
}
靜態 blank final
public class Config {
private static final String DATABASE_URL;
static {
// 在靜態區塊中初始化
DATABASE_URL = loadFromConfig();
}
private static String loadFromConfig() {
return "jdbc:mysql://localhost:3306/db";
}
}
實際應用
不可變類別
public final class Money {
private final int amount;
private final String currency;
public Money(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
public int getAmount() {
return amount;
}
public String getCurrency() {
return currency;
}
// 不提供 setter,物件建立後不可修改
public Money add(Money other) {
if (!this.currency.equals(other.currency)) {
throw new IllegalArgumentException("貨幣不同");
}
return new Money(this.amount + other.amount, this.currency);
}
}
工具類別常數
public class HttpStatus {
public static final int OK = 200;
public static final int NOT_FOUND = 404;
public static final int INTERNAL_SERVER_ERROR = 500;
private HttpStatus() {} // 防止實例化
}
模板方法模式
public abstract class DataProcessor {
// final 方法定義演算法骨架
public final void process() {
readData();
processData();
writeData();
}
protected abstract void readData();
protected abstract void processData();
protected abstract void writeData();
}
final 的好處
- 安全性:防止意外修改
- 執行緒安全:final 欄位是執行緒安全的
- 效能:編譯器可以優化
- 設計意圖:明確表達不應被修改
何時使用 final
| 情況 | 建議 |
|---|---|
| 常數 | public static final |
| 不可變欄位 | private final |
| 不應被覆寫的方法 | final 方法 |
| 不應被繼承的類別 | final 類別 |
| Lambda 中使用的變數 | final 或 effectively final |