this 是 Java 中代表「目前物件實例」的參考變數,廣泛用於解決變數遮蔽、物件傳遞、內部類別存取外部實例等場景。本文系統整理三大核心用法,附完整可執行範例與記憶體模型解析。
當區域變數(含建構子參數、方法參數)與實例變數同名時,this 明確指向實例欄位。
public class ThisDemo {
private String name = "預設名稱";
public ThisDemo(String name) {
// 參數 name 遮蔽了實例變數 name
System.out.println("參數 name = " + name); // 參數
System.out.println("建構前 this.name = " + this.name); // 實例變數
this.name = name; // 將參數值指派給實例變數
System.out.println("建構後 this.name = " + this.name);
}
public static void main(String[] args) {
new ThisDemo("自訂名稱");
}
}
輸出:
參數 name = 自訂名稱
建構前 this.name = 預設名稱
建構後 this.name = 自訂名稱
常見於回呼註冊、建構器鏈結、建構者模式等場景。
class Printer {
void print(String msg) {
System.out.println("[Printer] " + msg);
}
}
class Task {
private Printer printer;
// 建構子接收外部 Printer,並將自己(this)註冊為監聽者
Task(Printer printer) {
this.printer = printer;
printer.print("Task 建立完成,註冊回呼");
}
void execute() {
printer.print("Task 正在執行...");
}
}
public class ThisReferenceDemo {
public static void main(String[] args) {
Printer printer = new Printer();
Task task = new Task(printer); // 這裡的 printer 是外部建立的
task.execute();
}
}
在匿名內部類別或非靜態內部類別中,this 指向內部類別實例;需用 外部類別名.this 存取外部實例。
public class OuterClass {
private int counter = 0;
public void startAsyncTask() {
// 匿名內部類別實作 Runnable
new Thread(() -> {
// 這裡的 this 指向 Runnable 實例,非 OuterClass
// 必須用 OuterClass.this 存取外部實例
for (int i = 0; i < 3; i++) {
OuterClass.this.incrementAndPrint();
try { Thread.sleep(500); } catch (InterruptedException ignored) {}
}
}).start();
}
private void incrementAndPrint() {
System.out.println("Counter: " + ++counter);
}
public static void main(String[] args) {
new OuterClass().startAsyncTask();
}
}
this(...) 呼叫同類別其他建構子,必須置於建構子第一行。
public class ConstructorChaining {
private String id;
private String name;
private int age;
// 主建構子
public ConstructorChaining(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 便利建構子:預設年齡 18
public ConstructorChaining(String id, String name) {
this(id, name, 18); // 呼叫主建構子
}
// 便利建構子:全部預設
public ConstructorChaining() {
this("UNKNOWN", "Guest", 18);
}
}
| 誤區 | 正確做法 |
|---|---|
| 在 static 方法中使用 this | static 方法屬於類別,無 this;改用類別名存取靜態成員 |
| Lambda 表達式中 this 指向外部類別 | Lambda 無 this,直接存取外部 final/實際最終變數;需外部實例時用 外部類別.this |
| 建構子中呼叫 this() 非第一行 | this()/super() 必須是建構子第一行敘述 |
this 儲存在堆疊幀的區域變數表第 0 位(this reference)。this。OuterClass.this),可能導致外部物件無法 GC,注意記憶體洩漏風險。this 是 Java 物件導向核心機制之一,掌握其三大用法——消除遮蔽、傳遞自身參考、內部類別穿透存取——能寫出更清晰、正確的程式碼。建構子鏈結更是減少重複代碼的關鍵技巧。