Java-在匿名内部类中使用非final变量?
在一次学校测试中,我在一个匿名的内部班级中使用了非最终变量。 在学校电脑和我的私人电脑(使用x86 jre1.8.0_45)上,它工作正常 但是,Eclipse在笔记本电脑上显示错误(变量应使用final)。他正在使用jre1.8.0.x版本(不知道确切的版本) 你知道为什么它在我的电脑上工作而不是在他的电脑上吗 在此代码示例中,在ActionListener的actionPerformed函数中使用了NoFinal对象jLabel:Java-在匿名内部类中使用非final变量?,java,Java,在一次学校测试中,我在一个匿名的内部班级中使用了非最终变量。 在学校电脑和我的私人电脑(使用x86 jre1.8.0_45)上,它工作正常 但是,Eclipse在笔记本电脑上显示错误(变量应使用final)。他正在使用jre1.8.0.x版本(不知道确切的版本) 你知道为什么它在我的电脑上工作而不是在他的电脑上吗 在此代码示例中,在ActionListener的actionPerformed函数中使用了NoFinal对象jLabel: import java.awt.event.ActionEv
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
public class Main {
public Main(String[] args) {
JLabel jLabel = new JLabel();
JButton button = new JButton();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
jLabel.setText("xyz");
}
});
}
}
较新的java版本在这方面更加宽容:它们只要求它们应该是“有效的最终版本” 最后,差别并不是那么大——您只能使用可以标记为
final
的变量;您不能修改它们
如果你在那个地方,你也可以让他们“真的”final
,而且它在任何地方都有效
顺便说一句,在1.8上,使用新的lambda语法,您可以编写得更加优雅
button.addActionListener((ActionEvent arg0) -> jLabel.setText("xyz"));
您可以将侦听器定义为私有内部类,而不是匿名类,以避免该问题:
public class Main {
public Main(String[] args) {
JLabel jLabel = new JLabel();
JButton button = new JButton();
button.addActionListener(new MyActionListener(jLabel));
}
private class MyActionListener implements ActionListener {
private JLabel jLabel;
MyActionListener(JLabel jLabel) {
this.jLabel = jLabel;
}
@Override
public void actionPerformed(ActionEvent arg0) {
jLabel.setText("xyz");
}
}
}
通过这种方式,您可以将标签(和按钮,如果需要)传递给侦听器的构造函数,并且可以毫无问题地使用它。听起来很奇怪,应该是一个字段变量,或者声明为final,据我所知,这是警告还是错误?可能是重复的声音,就像他将eclipse配置为目标(编译为)Java1.7。即使安装了Java1.8,这也是可能的,因为eclipse包含自己的编译器,更确切地说,“有效的最终版”是从Java1.8引入的。。。在以前的版本中,它必须被宣布为最终版本。@Codebender我也这么认为,但OP似乎也观察到了1.8版本中的这种“旧”行为-如果他没有错的话…“新”是相对的。7及以上为EoPU,已过时,不应再使用。