关于编译器错误Cannot refer to a non-final variable message inside an inner class defined in a different method
,有一些关于Stack
Overflow的主题,解决方案是“将其声明为最终的,您就完成了”,但是对于这个 理论性的 问题,我想检查一下该代码无法编译的逻辑原因是什么:
private void updateStatus(String message) {
Runnable doUpdateStatus = new Runnable() {
public void run() {
/* do something with message */
}
}
/* do something with doUpdateStatus, like SwingUtilities.invokeLater() */
}
(解决方案:声明message
为final),而这一点却做到了:
private String enclosingClassField;
private void updateStatus() {
Runnable doUpdateStatus = new Runnable() {
public void run() {
/* do something with enclosingClassField */
}
}
/* do something with doUpdateStatus, like SwingUtilities.invokeLater() */
}
我真的很困惑
enclosingClassField
不是最终值,它可以多次更改,而的可怜message
参数updateStatus
只能在其方法体内更改,而是由编译器负责;)
甚至编译器错误也误导了我。Cannot refer to a non-final variable message inside an inner class defined in a different method
:
与什么不同?message
与内部类不是在同一方法中定义的吗?是不是enclosingClassField
该方法之外,而不是定义?嗯…
有人可以指出我对此事的正确解释吗?谢谢。
区别在于局部(方法)变量与类成员变量之间。成员变量在封闭对象的生存期内存在,因此可以由内部类实例引用。但是,局部变量仅在方法调用期间存在,并且由编译器以不同方式处理,因为它的隐式副本作为内部类的成员生成。如果不将局部变量声明为final,则可以对其进行更改,由于内部类仍在引用该变量的原始值,从而导致细微的错误。
更新:
Java专家通讯25号对此进行了更详细的讨论。
甚至编译器错误也误导了我。
Cannot refer to a non-final variable message inside an inner class defined in a different method
: 与什么不同?
run
我相信从内层阶级的方法。
本地风险值背后的想法是最终的,而领域不是。
在此代码示例中,ActionListener的actionPerformed函数中没有使用最终对象jLabel:
问题内容: 我有按钮单击侦听器,并且在方法中我有一个局部变量,例如 为什么Java要求让我最终决定? 问题答案: 当onCreate()方法返回时,您的局部变量将从堆栈中清除,因此它们将不再存在。但是匿名类对象new View.OnClickListener()引用了这些变量。当然,这是错误的行为,因此Java不允许您执行此操作。 最终确定后,它将成为一个常数。因此它存储在堆中,可以在匿名类中安全
问题内容: 我想知道使用最终局部变量是否有可用性。当继承出现时,变量无论如何都不会被覆盖。例如下面的简单代码 这个例子很简单,可能不是一个相关的代码,但是问题比较笼统。我已经看到了很多代码(全部都包含在具有最终局部变量的main函数中)是否有将局部变量声明为final other的可用性。不能在同一功能中进行编辑? 问题答案: 首先,关于变量被“覆盖”的部分具有两个非常不同的含义。对于类和方法,它
为什么<code>test
我正在写一个程序,我得到这样的结果:“最后的局部变量asd不能被赋值,因为它是在一个封闭类型中定义的”。 我将提供一个示例,它不是来自我的代码,但这也会产生错误。我有一个arraylist,我想以后在按钮之外使用它(如果我在按钮内部定义它,以后就不能使用它了),但是按下按钮应该会给这个arraylist提供值。在本例中,它将“创建一个新的ArrayList”,这将导致同样的问题。