首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java static 關鍵字深度解析:靜態成員、靜態區塊與記憶體模型

     編輯:Java 相關知識

static 核心語意:歸屬於類別而非實例

static 修飾的成員(變數、方法、區塊、內部類別)屬於類別本身,不依賴任何具體實例即可存取。JVM 在類別載入階段於方法區分配記憶體,所有實例共享同一份靜態資料。

四大靜態成員類型詳解

1. 靜態變數(類別變數)

public class Counter {
    private static int count = 0;  // 靜態變數
    private int instanceCount = 0; // 實例變數

    public Counter() {
        count++;
        instanceCount++;
    }

    public static int getCount() { return count; }
    public int getInstanceCount() { return instanceCount; }
}
  • 記憶體僅分配一次,節省空間
  • 透過 類別名.靜態變數 存取(推薦),亦可透過實例存取(不推薦,編譯器會警告)
  • private static 限制外部類別直接存取,僅允許本類別靜態方法/區塊使用

2. 靜態方法

public class MathUtils {
    public static int add(int a, int b) { return a + b; }
    // 編譯錯誤:靜態方法無法存取 this/super
    // public static void printInstance() { System.out.println(this); }
}

限制:無法直接呼叫非靜態成員、無法使用 this/super、不能宣告為 abstract(因為靜態方法屬於類別,無法被覆寫,只能被隱藏)。

3. 靜態初始化區塊

public class DatabaseConfig {
    private static String URL;
    private static Connection POOL;

    static {
        // 類別載入時執行,按出現順序依序執行
        try {
            URL = "jdbc:mysql://localhost:3306/mydb";
            POOL = DriverManager.getConnection(URL, "user", "pass");
            System.out.println("資料庫連線池初始化完成");
        } catch (SQLException e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}
  • 類別載入時由 JVM 自動執行,僅執行一次
  • 常用於複雜靜態資料初始化、載入原生庫、註冊 JDBC 驅動等
  • 若拋出未檢查例外,會包裝為 ExceptionInInitializerError

4. 靜態內部類別


public class Outer {
    private static String config = "CFG";
    static class Nested {
        void print() { System.out.println(config); } // 可存取外部類別靜態成員
    }
}

靜態內部類別不持有外部類別實例參考,適合實作單例模式、建構者模式等。

static final:編譯期常數與執行期不可變


public class Constants {
    public static final double PI = 3.14159;           // 編譯期常數,內聯優化
    public static final List IMMUTABLE_LIST =  // 執行期不可變集合
        Collections.unmodifiableList(Arrays.asList("A", "B", "C"));
}
  • 基本型別與 String 為編譯期常數,編譯器會內聯到呼叫端
  • 參考型別僅保證參考不變,物件內容仍可修改(除非物件本身不可變)

記憶體模型與執行緒可見性

static 變數儲存在堆區的類別物件中(JDK 8 移除 PermGen,改用 Metaspace)。多執行緒存取靜態變數時,需注意:

  • volatile 保證可見性與禁止指令重排
  • AtomicInteger 等原子類別提供無鎖執行緒安全操作
  • 雙重檢查鎖定單例模式必須配合 volatile
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved