前幾章聚焦於物件(實例)層級的欄位與方法。本章轉向類別層級——屬於類別本身、為所有實例共享的靜態成員與靜態方法,以及定義不可變契約的 final 關鍵字。
用 static 修飾的欄位稱為類別變數或靜態欄位。它不屬於任何單一物件,而是屬於類別本身,在記憶體中僅存在一份,所有實例共享。
class Human {
private int height; // 實例欄位:每個人各有各的身高
private static int population = 0; // 靜態欄位:全人類共享的人口計數
public static final boolean IS_MAMMAL = true; // 常數:全人類共享的屬性
public Human(int h) {
this.height = h;
Human.population++; // 建構子中更新類別狀態
}
public static int getPopulation() { return population; } // 靜態方法存取靜態欄位
}
// 1. 透過類別名(推薦,語義清晰)
System.out.println(Human.getPopulation());
System.out.println(Human.IS_MAMMAL);
// 2. 透過實例參考(合法但不推薦,易誤導以為是實例欄位)
Human p = new Human(170);
System.out.println(p.getPopulation()); // 編譯器實際轉為 Human.getPopulation()
static 方法不接收隱式 this 參考,因此:
this 或 super。
Math.max(), Collections.sort()LocalDate.now()getInstance()Human.getPopulation()實例方法可以存取靜態欄位。這是實現「物件生命週期影響類別統計」的關鍵:
public Human(int h) {
this.height = h;
Human.population++; // 實例建構時,類別計數 +1
}
// 也可在實例方法中修改
public void die() { Human.population--; }
| 修飾對象 | 含義 | 備註 |
|---|---|---|
| 基本型別變數 | 編譯期常數,賦值一次後不可變 | 慣例全大寫 MAX_SIZE |
| 參考型別變數 | 參考不可變(不可指向新物件),但物件內容可變 | 類似 C 的 int * const ptr |
| 方法 | 不可被覆寫 | private 方法隱含 final |
| 類別 | 不可被繼承 | String, Integer 等皆為 final |
class MathConstants {
public static final double PI = 3.141592653589793; // 編譯期內聯到呼叫處
public static final int MAX_INT = Integer.MAX_VALUE;
}
編譯器會將 MathConstants.PI 直接替換為字面值,無運行期存取開銷。
| 呼叫者 \ 被存取 | 實例欄位 | 靜態欄位 | 實例方法 | 靜態方法 |
|---|---|---|---|---|
| 實例方法 | ✅ | ✅ | ✅ | ✅ |
| 靜態方法 | ❌ | ✅ | ❌ | ✅ |
private,提供靜態存取器(如 getPopulation()),保留封裝彈性。MAX_CONNECTIONS),語義明確。final List list = new ArrayList<>(); list.add("a"); // 合法 。final 修飾方法/類別,明確設計意圖,助編譯器優化(內聯、去虛擬化)。static 將欄位/方法提升至類別層級,**全域單份、共享狀態**。this**,只能操作靜態成員。final 三重語義:基本型常數、參考不可變、禁止覆寫/繼承。static final 是真正的編譯期常數,零開銷。設計原則:「預設實例化,必要時靜態」。濫用靜態會導致強耦合、難測試、執行緒不安全。只有真正屬於「類別本身」的狀態與行為,才配得上
static。