ClassName.staticMemberpublic class TStatic {
static int i; // 類載入時初始化為 0
public TStatic(int j) { i = j; }
public static void main(String[] args) {
System.out.println(TStatic.i); // 0
TStatic t = new TStatic(5); // i=5
System.out.println(t.i); // 5
TStatic tt = new TStatic(); // i=4
System.out.println(t.i); // 4 (tt 修改影響 t)
System.out.println(tt.i); // 4
}
}
輸出:0, 5, 4, 4, 4 — 驗證所有實例共享同一 i。
class ClassA {
static int b;
static void ex1() {}
}
class ClassB {
void ex2() {
int i = ClassA.b; // 類名存取靜態變數
ClassA.ex1(); // 類名呼叫靜態方法
}
}
JVM 載入類時即分配靜態空間,無需實例化。
public class StaticCls {
public static void main(String[] args) {
new OuterCls.InnerCls(); // 直接建立,無需 OuterCls 實例
}
}
class OuterCls {
public static class InnerCls {
InnerCls() { System.out.println("InnerCls"); }
}
}
輸出:InnerCls — 靜態內部類可作為獨立類使用。
static { ... } 用於顯式初始化,類首次載入時執行一次class Count {
Value v = new Value(10); // 實例變數,最後初始化
static Value v1, v2; // 靜態變數,最早初始化 (null)
static {
v1 = new Value(27); // 靜態區塊依序執行
v2 = new Value();
}
}
public class TStaticBlock {
public static void main(String[] args) {
Count ct = new Count(); // 觸發類載入與實例化
// 輸出驗證靜態區塊執行順序與共享特性
}
}
關鍵觀察:v1、v2、ct.v 最終操作同一靜態變數 Value.c,體現靜態成員跨實例共享本質。
| 誤區 | 正確理解 |
|---|---|
| static 變數可在任意處初始化 | 只能在宣告處或建構子中初始化,且僅一次 |
| static 方法可用 this/super | 靜態語境無 this,編譯錯誤 |
| 靜態方法不可被覆寫 | 可被子類「隱藏」(同簽名靜態方法),非多型覆寫 |
| 大量使用 static 提升效能 | 破壞 OO 封裝、難以測試、併發風險,慎用 |
public static final TYPE NAME = VALUE; — 唯一標準常數形式Math, Collections)Atomic* 類別