[英]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.