在 Java 中,static
是一個修飾符,用于定義與類相關(而非對象實例相關)的成員。以下是核心知識點和用法:
一、四大用途
-
靜態變量(類變量)
- 作用:屬于類,而非實例。所有實例共享同一副本。
- 內存分配:類加載時在方法區內存中分配。
- 示例:
public class Counter {static int count = 0; // 靜態變量public Counter() { count++; } }
Counter c1 = new Counter(); // count=1 Counter c2 = new Counter(); // count=2 (共享)
-
靜態方法(類方法)
- 規則:
- 只能訪問靜態成員(變量/方法)。
- 不能使用
this
或super
。 - 可通過類名直接調用。
- 示例:
public class MathUtils {public static int add(int a, int b) {return a + b;} } // 調用:MathUtils.add(3, 5);
- 規則:
-
靜態代碼塊
- 作用:在類加載時執行一次,用于初始化靜態資源。
- 執行順序:按定義順序執行。
- 示例:
public class Database {static {System.out.println("加載數據庫驅動..."); // 類加載時執行} }
-
靜態內部類
- 特點:
- 不依賴外部類實例。
- 無法訪問外部類的非靜態成員。
- 示例:
public class Outer {static class Nested { // 靜態內部類void print() { System.out.println("Nested"); }} } // 使用:Outer.Nested obj = new Outer.Nested();
- 特點:
二、關鍵特性
-
生命周期
- 從類加載開始,到 JVM 結束銷毀。
- 比實例成員的生命周期長。
-
內存分配
- 靜態變量/方法:存儲在方法區(JDK 8+ 的元空間)。
- 實例變量/方法:存儲在堆內存的對象中。
-
訪問限制
- 靜態方法中 不能直接訪問非靜態成員(需要先創建對象)。
- 非靜態方法可以自由訪問靜態成員。
三、使用場景
-
共享數據配置
public class AppConfig {public static final String API_KEY = "ABC123"; // 全局常量 }
-
工具類設計
public class StringUtils {private StringUtils() {} // 防止實例化public static boolean isEmpty(String s) { ... } }
-
單例模式
public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;} }
四、常見誤區
-
重寫問題
static
方法不能被重寫(Override),只支持方法隱藏(Method Hiding):class Parent {static void print() { System.out.println("Parent"); } } class Child extends Parent {static void print() { System.out.println("Child"); } // 隱藏父類方法 }
-
多態失效
靜態方法在編譯時綁定,不存在運行時多態:Parent obj = new Child(); obj.print(); // 輸出 "Parent"(編譯時類型決定)
-
線程安全問題
多個線程同時修改靜態變量需同步:public class Counter {private static int count;public static synchronized void increment() { count++; } // 加鎖 }
五、與 final
結合
- 靜態常量:固定不變的值(如數學常量)
public class Constants {public static final double PI = 3.1415926; }
六、總結
特性 | static 成員 | 非靜態成員 |
---|---|---|
歸屬 | 類 | 對象實例 |
內存分配時機 | 類加載時 | 創建對象時 |
訪問方式 | 類名.成員 或對象訪問 | 必須通過對象訪問 |
生命周期 | 與類相同 | 與對象相同 |
多態支持 | 不支持(靜態綁定) | 支持(動態綁定) |
最佳實踐:優先用 static
定義工具方法、常量,避免濫用導致代碼耦合或內存泄漏。