finish() 如何在 OnClick 事件中工作?

How does finish() work in OnClick event?

我有一个 Activity,只有一个按钮可以退出 Activity

通过 layout.xml 我必须将 OnClick 事件设置为 cmd_exit 并且调用 'this.finish()' 可以正常工作

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

,但是当我添加 OnClickListener 而不是

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

this.finish() 给出错误。它只能是 finish().

我知道 finish() 住在 Activity class 所以我的问题是它在第二个片段中是如何工作的?

在第一种情况下 this 指的是 Activity 实例。在第二种情况下,您有一个用 new View.OnClickListener() 实例化的 anonymous inner class,其 this 指的是 class 的实例。每个匿名内部 class 都有一个对其实例化的外部 class 的隐式引用。调用 finish() 时隐式使用该引用,即 OuterClassName.this.finish().

How is it working in the second snippet?

编译器负责将对外部 class 实例的引用传递到内部 class。它通过添加对外部 class 实例的引用作为构造函数参数来修改每个内部 class' 构造函数。


参考:Core Java Volume I - Fundamentals, 9th Edition,第 6.4 章:内在 类,第 309 页


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

当您将 OnClickListener 创建为匿名 class 时,this 关键字引用该侦听器实例而不是封闭的 class。您可以改用 YourActivityClassName.this。您也可以省略 this,因为 OnClickListener 没有 finish() 方法,所以将使用 Activity 方法。