public class Person {
private String name;
public void setName(String name) {
this.name = name; // 區分字段與參數
}
public Person self() {
return this; // 返回當前對象引用,支援鏈式調用
}
}
用於:字段/參數同名消歧義、返回當前對象、傳遞當前對象給其他方法。
public class Point {
private int x, y;
private String label;
public Point() {
this(0, 0); // 必須是構造器第一條語句
}
public Point(int x, int y) {
this(x, y, "origin"); // 呼叫三參構造器
}
public Point(int x, int y, String label) {
this.x = x;
this.y = y;
this.label = label;
}
}
規則:this(...) 必須置於構造器首行;一個構造器只能調用一個 this(...);不能與 super(...) 共存。
public class Outer {
private int value = 10;
public class Inner {
public void print() {
System.out.println(Outer.this.value); // 訪問外部類字段
System.out.println(this.value); // 訪問內部類字段 (若存在)
}
}
}
public class EventSource {
private List listeners = new ArrayList<>();
public void addListener(Listener l) { listeners.add(l); }
public void removeListener(Listener l) { listeners.remove(l); }
protected void fireEvent() {
for (Listener l : listeners) l.onEvent(this);
}
}
public class MyComponent implements Listener {
private final EventSource source;
public MyComponent(EventSource source) {
this.source = source;
source.addListener(this); // 構造器中傳遞 this!
}
@Override public void onEvent(Object src) { ... }
}
在構造器完成前,對象 尚未完全初始化 (字段可能為默認值、不變量未建立)。若 this 被發布 (存入集合、註冊監聽、啟動線程),其他執行緒/代碼可能看到 部分構造狀態,導致不可預期錯誤。
public static MyComponent create(EventSource source) {
MyComponent comp = new MyComponent();
comp.init(source); // 完全構造後註冊
return comp;
}
private MyComponent() {} // 私有構造器
private void init(EventSource source) {
this.source = source;
source.addListener(this);
}
super() 顯式或隱式調用)this(...) 鏈最終到達的構造器體)class Parent {
Parent() { System.out.println("Parent()"); }
}
class Child extends Parent {
Child() { this(10); System.out.println("Child()"); }
Child(int x) { System.out.println("Child(int)"); }
}
new Child();
// 輸出:
// Parent()
// Child(int)
// Child()
關鍵點:Child() 調用 this(10),Child(int) 隱式調用 super(),故先執行父構造器。
public class SafePublish {
private final int value; // final 字段
public SafePublish(int v) {
value = v;
// 此處 this 逃逸安全:JMM 保證 final 字段寫入對其他線程可見
// 前提:構造器內未發布 this (或僅發布給不依賴 final 字段的代碼)
}
}
JMM (Java Memory Model) 保證:正確構造的對象 (無 this 逃逸),其 final 字段在構造器結束前的寫入,對所有線程可見,無需同步。
| 場景 | 建議 |
|---|---|
| 字段/參數同名 | 必加 this. 消歧義 |
| 構造器鏈 | 善用 this(...) 減少重複代碼 |
| 內部類訪問外部 | 使用 OuterClass.this |
| 構造器中傳遞 this | 極力避免;改用工廠/兩階段初始化 |
| 並發環境構造 | 所有字段 final + 無 this 逃逸 = 安全發布 |
| 方法鏈式調用 | 返回 this 實現流暢 API |
this 看似簡單,實則涉及 對象構造生命週期、內存可見性、封裝邊界 等核心機制。理解「構造器中 this 逃逸」風險,是從初級進階為高級 Java 開發者的關鍵門檻之一。