`this` 是 Java 中指向**當前對象實例**的引用,僅能在**非靜態上下文** (實例方法、構造器、實例初始化塊) 中使用。本文通過代碼示例、字節碼視角、實戰陷阱三個維度,徹底講透 `this` 的三大核心用法。
public class User {
private String name; // 實例變量
private int age;
public User(String name, int age) {
name = name; // 錯誤!局部變量賦值給局部變量,實例變量仍為 null
age = age;
}
}
public User(String name, int age) {
this.name = name; // this.name 明確指向實例變量
this.age = age;
}
// 反編譯構造器
public User(java.lang.String, int);
Code:
0: aload_0
1: invokespecial #1 // Object.
4: aload_0
5: aload_1 // 載入局部變量 name (slot 1)
6: putfield #2 // this.name = name
9: aload_0
10: iload_2 // 載入局部變量 age (slot 2)
11: putfield #3 // this.age = age
14: return
`aload_0` 載入 `this` (slot 0),`putfield` 寫入實例字段。無 `this` 則無 `aload_0`,直接 `astore_1` 寫回局部變量槽。
public class User {
private String name;
private int age;
private String email;
public User() { this("匿名"); } // 調用單參構造器
public User(String name) { this(name, 0); } // 調用雙參構造器
public User(String name, int age) { // 全參構造器 (入口)
this.name = name;
this.age = age;
}
public User(String name, int age, String email) {
this(name, age); // 復用雙參邏輯
this.email = email;
}
}
規則: `this(...)` **必須置於構造器首行**,一個構造器只能調用一次,避免遞歸死循環。
public class User {
private String name;
private int age;
public User setName(String name) {
this.name = name;
return this; // 返回當前對象
}
public User setAge(int age) {
this.age = age;
return this;
}
}
// 使用:一行代碼完成多屬性設置
User user = new User().setName("李四").setAge(25);
這是 **Builder 模式**、**Fluid API** (如 `StringBuilder.append()`、Stream API) 的核心實現機制。
public class Order {
private User buyer;
public Order(User buyer) {
this.buyer = buyer;
}
}
public class User {
private String name;
public void placeOrder() {
Order order = new Order(this); // 將當前 User 傳給 Order
// order 現在持有對 this 的引用
}
}
public class Outer {
private int value = 100;
class Inner {
public void print() {
System.out.println(Outer.this.value); // 顯式訪問外部類實例
}
}
}
public void synchronizedMethod() {
synchronized (this) { // 鎖住當前對象實例
// 臨界區
}
}
| 陷阱 | 錯誤代碼 | 正確代碼 | 原因 |
|---|---|---|---|
| 靜態方法使用 this | static void f() { this.x = 1; } | 去掉 this 或改為實例方法 | 靜態上下文無當前對象 |
| 構造器中調用可覆寫方法 | public A() { init(); } void init(){} | init() 設為 final/private | 子類覆寫 init 時 this 尚未完全構造 |
| Lambda 中 this 指向 | Runnable r = () -> { this.run(); } | this 指向外部類實例 (非 Runnable 實例) | Lambda 無自身 this,捕獲外部 this |
| 內部類影子 this | class Inner { void f() { this.value; } } | Outer.this.value 訪問外部 | Inner 的 this 遮蔽 Outer 的 this |
區分同名:構造器 Setter 必加 this,實例變量不迷路。
鏈式返回:Setter 返回 this,Builder 流式寫法最優雅。
傳遞引用:內部類訪外部、同步鎖當前、構造器鏈調用,this 到處可傳遞。
靜態禁用:static 方法裡沒有 this,編譯報錯別忘記。
掌握 `this` 三大用法,等於掌握了**對象自我引用**的核心編程技巧,是寫出優雅 Java 代碼的基石。