Java 修飾符完整指南:存取控制、非存取修飾符與最佳實踐
修飾符定義類別、方法、變數的語意與可見性,置於宣告最前端。
public class ClassName { ... }
private boolean flag;
static final double WEEKS = 9.5;
protected static final int BOX_WIDTH = 42;
public static void main(String[] args) { ... }
存取控制修飾符 (四種等級)
| 修飾符 | 同一類別 | 同一套件 | 子類別(不同套件) | 其他套件 |
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
default (無修飾符) | Y | Y | N | N |
private | Y | N | N | N |
詳細說明
- public: 完全公開,跨套件需
import。main() 必須為 public。
- protected: 同套件 + 子類別(含跨套件)。介面成員不可為 protected。用於「僅開放給繼承體系」。
- default (package-private): 僅同套件可見。介面隱式
public static final (欄位) / public (方法)。
- private: 僅類別內部可見。類別/介面不可為 private。配合
getter/setter 封裝資料。
存取控制與繼承規則
- 父類
public 方法 → 子類必須 public。
- 父類
protected 方法 → 子類只能 protected 或 public,不可 private。
- 父類
private 方法 → 子類不可繼承(不可見)。
非存取修飾符
static:類別層級成員
- 靜態變數 (類別變數): 全類別共享單一副本,
ClassName.var 存取。區域變數不可 static。
- 靜態方法: 無
this,只能存取靜態成員。ClassName.method() 呼叫。
- 靜態區塊:
static { ... } 類別載入時執行一次,用於複雜靜態初始化。
範例:單例計數器
public class InstanceCounter {
private static int count = 0;
private static void add() { count++; }
public static int getCount() { return count; }
public InstanceCounter() { add(); }
public static void main(String[] args) {
System.out.println("起始: " + getCount());
for (int i=0; i<500; i++) new InstanceCounter();
System.out.println("建立後: " + getCount());
}
}
// 輸出:起始: 0 / 建立後: 500
final:不可變更
| 修飾目標 | 效果 |
| 類別 | 不可被繼承 (final class) |
| 方法 | 不可被覆寫 |
| 變數 | 只能賦值一次 (常量)。引用不可變,物件內容仍可修改。 |
常與 static 合用定義常量:public static final int MAX = 100;
abstract:抽象化
- 抽象類別:
abstract class 不可實例化,供繼承擴充。含抽象方法則類別必須 abstract。
- 抽象方法:
abstract void m(); 無主體,分號結尾。子類必須實作 (除非子類也 abstract)。
- 不可同時
abstract 和 final。
synchronized:執行緒同步
public synchronized void method() { ... }
// 同一時間僅一執行緒可進入該方法 (鎖定 this / Class 物件)
volatile:記憶體可見性
- 強制從主記憶體讀寫,保證多執行緒見到最新值。
- 不保證原子性 (複合操作仍需同步)。
- 常用於狀態旗標:
private volatile boolean running = true;
transient:序列化排除
private transient int temp; // 序列化時忽略此欄位
private int persistent; // 正常序列化
修飾符組合總結表
| 目標 | 可用修飾符組合 |
| 類別 | public / default / final / abstract / strictfp |
| 介面 | public / default / abstract / strictfp |
| 建構子 | public / protected / default / private |
| 方法 | 四大存取 + static / final / abstract / synchronized / native / strictfp |
| 欄位 | 四大存取 + static / final / transient / volatile |
| 區域變數 | final (唯一) |
封裝最佳實踐
- 欄位 私有化 (
private)。
- 提供
public getter/setter 控制存取邏輯 (驗證、日誌、延遲初始化)。
- 常量用
public static final (大寫底線命名)。
- 工具方法、工廠方法用
static。
- 設計給繼承用的內部方法用
protected。
- 多執行緒共享可變狀態用
volatile 或 synchronized / Lock。