简体   繁体   English

定义为匿名内部类的Java事件侦听器如何使用封闭类中的变量?

[英]How can an java event listener defined as an anonymous inner class use a variable from an enclosing class?

Here's the code: 这是代码:

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;
}

How does the anonymous inner class (the OnClickListener) have access to the button2 variable? 匿名内部类(OnClickListener)如何访问button2变量? Its onClick method is called at some random time in the future when button is clicked. 在将来单击button时,将在以后的某个随机时间调用其onClick方法。 In what context does this function run? 此功能在什么情况下运行? How does it know about button2 ? 它如何知道button2 I'm just confused about the scoping and context here. 我对这里的作用域和上下文感到困惑。

Often, the best way to find out how the Java compiler does something is to compile the class and then run it through Jad (JAva Decompiler). 通常,找出Java编译器如何执行操作的最佳方法是编译该类,然后通过Jad(JAva Decompiler)运行它。 In this case, it appears that javac just creates an extra variable on the anonymous inner class named "val$o" and initializes it in a static initializer. 在这种情况下,似乎javac只是在名为“ val $ o”的匿名内部类上创建了一个额外的变量,并在静态初始化程序中对其进行了初始化。 Seeing this transformation makes it clearer why Java requires that you make the variable final before using it in an anonymous inner class. 看到这种转换,就更清楚了Java为什么要求在匿名内部类中使用变量之前将其定为final的原因。 Without the requirement, the two variables could end up with different values at runtime. 无需此要求,这两个变量在运行时最终可能具有不同的值。 Also, this is really no different than the mechanism Java uses to allow all inner classes (anonymous or named) access to their containing class. 而且,这实际上与Java允许所有内部类(匿名或命名)访问其包含类的机制没有什么不同。 You can see that the inner class contains a reference to the containing class's this variable, named "this$0". 您会看到内部类包含对包含类的this变量的引用,名为“ this $ 0”。

I compiled a simpler example: 我编译了一个更简单的示例:

public class Outer {

    public void outerMethod() {
        final Object o = "fromOuter";
        new Object() {
            public void innerMethod() {
                System.out.println(o);
            }
        }.innerMethod();
    }
}

and got this out the other end: 并从另一端得到了这一点:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM