Java-在匿名内部类中使用非final变量?

Java-在匿名内部类中使用非final变量?,java,Java,在一次学校测试中,我在一个匿名的内部班级中使用了非最终变量。 在学校电脑和我的私人电脑(使用x86 jre1.8.0_45)上,它工作正常 但是,Eclipse在笔记本电脑上显示错误(变量应使用final)。他正在使用jre1.8.0.x版本(不知道确切的版本) 你知道为什么它在我的电脑上工作而不是在他的电脑上吗 在此代码示例中,在ActionListener的actionPerformed函数中使用了NoFinal对象jLabel: import java.awt.event.ActionEv

在一次学校测试中,我在一个匿名的内部班级中使用了非最终变量。 在学校电脑和我的私人电脑(使用x86 jre1.8.0_45)上,它工作正常

但是,Eclipse在笔记本电脑上显示错误(变量应使用final)。他正在使用jre1.8.0.x版本(不知道确切的版本)

你知道为什么它在我的电脑上工作而不是在他的电脑上吗

在此代码示例中,在ActionListener的actionPerformed函数中使用了NoFinal对象jLabel:

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,已过时,不应再使用。