[英]How can an java event listener defined as an anonymous inner class use a variable from an enclosing class?
這是代碼:
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
if (id == DIALOG_SEARCH) {
dialog = new Dialog(this);
dialog.setContentView(R.layout.search_dialog_layout);
dialog.setTitle("Search Dialog");
Button button = (Button) dialog.findViewById(R.id.Button01);
final Button button2 = (Button) dialog.findViewById(R.id.Button02);
button2.setEnabled(false);
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
button2.setEnabled(true);
}
});
}
return dialog;
}
匿名內部類(OnClickListener)如何訪問button2變量? 在將來單擊button
時,將在以后的某個隨機時間調用其onClick方法。 此功能在什么情況下運行? 它如何知道button2
? 我對這里的作用域和上下文感到困惑。
通常,找出Java編譯器如何執行操作的最佳方法是編譯該類,然后通過Jad(JAva Decompiler)運行它。 在這種情況下,似乎javac只是在名為“ val $ o”的匿名內部類上創建了一個額外的變量,並在靜態初始化程序中對其進行了初始化。 看到這種轉換,就更清楚了Java為什么要求在匿名內部類中使用變量之前將其定為final的原因。 無需此要求,這兩個變量在運行時最終可能具有不同的值。 而且,這實際上與Java允許所有內部類(匿名或命名)訪問其包含類的機制沒有什么不同。 您會看到內部類包含對包含類的this變量的引用,名為“ this $ 0”。
我編譯了一個更簡單的示例:
public class Outer {
public void outerMethod() {
final Object o = "fromOuter";
new Object() {
public void innerMethod() {
System.out.println(o);
}
}.innerMethod();
}
}
並從另一端得到了這一點:
public class Outer {
public Outer()
{
}
public void outerMethod()
{
final Object o = "fromOuter";
(new Object() {
public void innerMethod()
{
System.out.println(o);
}
final Outer this$0;
private final Object val$o;
{
this$0 = Outer.this;
o = obj;
super();
}
}).innerMethod();
}
}
這里有一個相當詳盡的解釋: http : //renaud.waldura.com/doc/java/final-keyword.shtml#vars
您創建的任何匿名類都將保留對封閉類的引用,該引用使他們可以訪問外部類中的變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.