1

因此,当我遍历我的 Buttons 数组列表时,我试图设置它们的所有 onClickedListener()/onFocusChangedListener() 但是当涉及到修改更改数组列表中的按钮时,它告诉我它必须是最终的。

代码:

        for(Button aBtn : menu_Buttons)
    {
        aBtn.setOnFocusChangeListener(new OnFocusChangeListener(){

            @Override
            public void onFocusChange(View arg0, boolean changed) {
                Log.i("LC", "focus changed");
                if(changed)
                 {
                    aBtn.setTextColor(Color.parseColor("#FFFFFF"));
                     Log.i("LC", "true");
                 }
                 else
                 {
                     aBtn.setTextColor(Color.parseColor("#CD6839"));
                     Log.i("LC", "false");
                 }
            }
        });
    }

所以它要求它改为这样。

for(final Button aBtn : menu_Buttons)

有人可以向我解释一下吗,我现在不是在 100% 工作,我不明白为什么它必须是最终的。

我找到了使用其他方法遍历数组列表的其他方法,但这只是困扰我。

4

2 回答 2

1

让我们退后一步,看看这里发生了什么:

  1. 你有一个实例变量(按钮 aBtn)
  2. 您在内部类中引用此实例变量(新 OnFocusChangeListener(){...})

现在,重要的是要记住内部类的方法将在未定义的稍后日期被调用。因此,其中包含的方法与当前的执行流程是分开的。现在想象下面的代码:

   for(Button aBtn : menu_Buttons)
{
    aBtn.setOnFocusChangeListener(new OnFocusChangeListener(){

        @Override
        public void onFocusChange(View arg0, boolean changed) {
            Log.i("LC", "focus changed");
            if(changed)
             {
                aBtn.setTextColor(Color.parseColor("#FFFFFF"));
                 Log.i("LC", "true");
             }
             else
             {
                 aBtn.setTextColor(Color.parseColor("#CD6839"));
                 Log.i("LC", "false");
             }
        }
    });

   if(someCondition) {
      aBtn = someOtherButton;
   }
}

在这种情况下 aBtn 被改变了,那么当内部类的一个方法被调用时应该使用哪个 Button 实例呢?无论编译器选择哪一个,都会给程序员带来歧义,进而容易成为微妙且难以追踪的 bug 的来源。

通过在内部类中引用的实例变量上强制使用 final,编译器消除了这种歧义,并使编码正确的程序更容易。

于 2013-08-11T12:39:50.823 回答
1

final 关键字意味着您不能在其范围内更改变量的值。对于您的循环示例,您可以认为变量在循环底部超出范围,然后在循环顶部以新值返回范围。分配给循环内的变量将不起作用。

于 2013-08-11T12:35:34.320 回答