以下是代码:
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
?我只是对这里的范围和背景感到困惑。
答案 0 :(得分:2)
通常,了解Java编译器如何执行某些操作的最佳方法是编译该类,然后通过Jad(JAva Decompiler)运行它。在这种情况下,似乎javac只是在名为“val $ o”的匿名内部类上创建一个额外的变量,并在静态初始化程序中初始化它。看到这种转换,可以更清楚地说明为什么Java要求你在匿名内部类中使用变量之前将变量设为final。如果没有这个要求,这两个变量可能会在运行时以不同的值结束。此外,这与Java用于允许所有内部类(匿名或命名)访问其包含类的机制没有什么不同。您可以看到内部类包含对包含类的此变量的引用,名为“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();
}
}
答案 1 :(得分:1)
答案 2 :(得分:1)
您创建的任何匿名类都将保留对封闭类的引用,这使得它们可以访问外部类中的变量。