ClassName.this 是 Java 內部類存取外部類實例的專用語法。本文將從 this 三大基本用法切入,深入剖析內部類影子變數問題、OuterClass.this 的必要性與實戰場景。
this.field = field;)。this(...) 必須置於建構子首行。obj.method(this)、return this (Builder 模式)。public class Outer {
private String name = "Outer";
class Inner {
private String name = "Inner";
void print() {
System.out.println(name); // Inner
System.out.println(this.name); // Inner (this 指向 Inner 實例)
System.out.println(Outer.this.name); // Outer (關鍵語法!)
}
}
}
規則:內部類中裸 this 指向內部類實例;需用 OuterClass.this 明確存取外部類實例。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 錯誤:new Intent(this, Target.class) 這裡的 this 是 OnClickListener 實例
// 正確:
Intent intent = new Intent(MainActivity.this, TargetActivity.class);
startActivity(intent);
// 關閉外部 Activity
MainActivity.this.finish();
}
});
}
}
匿名內部類中 this 指向匿名類實例,必須用 OuterActivity.this 取得 Context。
public class Outer {
static class StaticInner {
void demo() {
// 編譯錯誤:Outer.this 無法在靜態內容中使用
// 靜態內部類不持有外部類引用
}
}
}
靜態內部類無 Outer.this 隱含引用,故無法使用該語法。
public class LambdaDemo {
String value = "Outer";
void test() {
Runnable r = () -> {
System.out.println(this.value); // Lambda 無 this,捕獲外部實例 → "Outer"
};
new Thread(r).start();
}
}
Lambda 沒有自己的 this,this 直接指向外層實例,無需 Outer.this。
| 情境 | this 指向 | 存取外部實例 |
|---|---|---|
| 一般類別 | 當前實例 | 直接用 this |
| 非靜態內部類/匿名類 | 內部類實例 | OuterClass.this |
| 靜態內部類 | 無外部實例引用 | 不可用 |
| Lambda 表達式 | 外層實例 | 直接用 this |
Context/Activity 時,明確寫 OuterClass.this,提升可讀性。static 內部類或 Lambda,避免隱含持有外部引用導致記憶體洩漏。