How does finish() work in OnClick event?

2019-05-04 19:19发布

问题:

I have an Activity with one button to quit the Activity.

Through the layout.xml I have to set the OnClick event to cmd_exit and a call to 'this.finish()' works fine

public void cmd_exit(View editLayout){
    this.finish();
}

, but when I add a OnClickListener instead

cmd_exit = (Button) this.findViewById(R.id.cmd_ExitApp);
cmd_exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
    finish();
    }
});

this.finish() gives error. It has to be only finish().

I understand that finish() lives in the Activity class so my question is how is it working in the second snippet?

回答1:

When you've created an OnClickListener as an anonymous class, the this keyword refers to that listener instance rather than the enclosing class. You could use YourActivityClassName.this instead. You could also just omit the this, and since OnClickListener doesn't have a finish() method so the Activity one will be used.



回答2:

In the first case this refers to the Activity instance. In the second case you have an anonymous inner class instantiated with new View.OnClickListener() whose this refers to the instance of the class. Each anonymous inner class has an implicit reference to the outer class it's been instantiated in. That reference is implicitly used when calling finish(), i.e. OuterClassName.this.finish().

How is it working in the second snippet?

The compiler is responsible for passing a reference to the outer class instance into the inner class. It modifies each of the inner class' constructors by adding the reference to the outer class instance as a constructor parameter.


Reference: Core Java Volume I - Fundamentals, 9th Edition, Chapter 6.4: Inner Classes, page 309


As @Gabe Sechan pointed out, in order to refer to the outer class within the anonymous inner class use OuterClassName.this. Reference: How do you get a reference to the enclosing class from an anonymous inner class in Java?.