本文詳細說明 Java 中靜態內部類的特性、使用場景,以及執行緒同步的核心機制與實作模式。
public class OuterClass {
private static String staticField = "外部類靜態欄位";
private String instanceField = "外部類實例欄位";
// 靜態內部類
public static class StaticNestedClass {
public void accessOuter() {
System.out.println(staticField); // ✅ 可存取外部類靜態成員
// System.out.println(instanceField); // ❌ 編譯錯誤:無法存取實例成員
}
}
// 非靜態內部類 (內部類)
public class InnerClass {
public void accessOuter() {
System.out.println(staticField); // ✅ 可存取靜態成員
System.out.println(instanceField); // ✅ 可存取實例成員
}
}
}
| 特性 | 靜態內部類 | 非靜態內部類 |
|---|---|---|
| 外部類實例依賴 | 不需要 | 需要 (隱含持有外部類引用) |
| 存取外部類成員 | 僅靜態成員 | 所有成員 (含私有) |
| 建立方式 | new OuterClass.StaticNestedClass() | outerInstance.new InnerClass() |
| 記憶體效率 | 較佳 (無外部引用) | 較差 (持有外部引用) |
| 序列化風險 | 無 | 會連帶序列化外部類 |
public class User {
private final String name;
private final int age;
private final String email;
private User(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.email = builder.email;
}
// 靜態內部類作為 Builder
public static class Builder {
private String name;
private int age;
private String email;
public Builder name(String name) { this.name = name; return this; }
public Builder age(int age) { this.age = age; return this; }
public Builder email(String email) { this.email = email; return this; }
public User build() { return new User(this); }
}
}
// 使用方式
User user = new User.Builder()
.name("張三")
.age(25)
.email("zhang@example.com")
.build();
public class SyncDemo {
private int count = 0;
private final Object lock = new Object();
// 1. 同步實例方法:鎖住 this
public synchronized void increment1() { count++; }
// 2. 同步靜態方法:鎖住 Class 物件
public static synchronized void increment2() { /* ... */ }
// 3. 同步區塊:自定義鎖物件 (推薦,粒度更細)
public void increment3() {
synchronized(lock) { // 或 synchronized(this)
count++;
}
}
}
| 工具類 | 用途 | 關鍵方法 |
|---|---|---|
| ReentrantLock | 可重入鎖,支援公平/非公平、可中斷、超時 | lock(), unlock(), tryLock() |
| ReadWriteLock | 讀寫分離鎖,多讀單寫 | readLock(), writeLock() |
| CountDownLatch | 倒數閂,等待多任務完成 | countDown(), await() |
| CyclicBarrier | 循環柵欄,多執行緒互相等待 | await() |
| Semaphore | 信號量,控制並發存取數量 | acquire(), release() |
| CompletableFuture | 非同步程式設計,鏈式組合 | supplyAsync(), thenApply() |
public class ProducerConsumer {
private final Queue queue = new LinkedList<>();
private final int capacity = 10;
private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
public void produce(int value) throws InterruptedException {
lock.lock();
try {
while (queue.size() == capacity) notFull.await();
queue.offer(value);
notEmpty.signal();
} finally { lock.unlock(); }
}
public int consume() throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) notEmpty.await();
int value = queue.poll();
notFull.signal();
return value;
} finally { lock.unlock(); }
}
}
public class Singleton {
private Singleton() {}
// 靜態內部類持有實例,類載入時才初始化
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
public class RequestContextHolder {
// 靜態內部類包裝 ThreadLocal
private static class ThreadLocalHolder {
static final ThreadLocal HOLDER = new ThreadLocal<>();
}
public static void setContext(RequestContext ctx) {
ThreadLocalHolder.HOLDER.set(ctx);
}
public static RequestContext getContext() {
return ThreadLocalHolder.HOLDER.get();
}
public static void clear() {
ThreadLocalHolder.HOLDER.remove();
}
}
掌握靜態內部類特性與同步機制,能寫出更安全、高效的並發程式。靜態內部類不持有外部引用的特性,使其成為 Builder、單例、ThreadLocal 等模式的最佳選擇;而正確使用同步工具則是多執行緒程式正確性的基石。