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?
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.
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?.