为什么它说“不能引用用不同方法定义的内部类中的非最终变量i”?

我有按钮点击监听器,在方法中我有一个局部变量,如onCreate()

 onCreate() {

 super.onCreate();

 int i = 10;

 Button button = (Button)findViewById(R.id.button);

 button.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            i++;
        }   
    });

为什么java要求使我成为最终?


答案 1

当 onCreate() 方法返回时,您的局部变量将从堆栈中清理出来,因此它们将不再存在。但是匿名类对象 new View.OnClickListener() 引用了这些变量。因为它是错误的行为,所以java不允许你这样做。

最终确定后,它成为一个常量。因此,它存储在堆中,并且可以安全地在匿名类中使用。


答案 2

您的匿名内部类通过获取局部变量的副本来引用其封闭范围 - 如果要更改匿名内部类中int的值,则需要执行一些黑客操作:

final int[] arr = new int[1];
arr[0] = 10;
Button button = (Button)findViewById(R.id.button);

button.setOnClickListener(new View.OnClickListener() {
  arr[0]++;
}

推荐