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

时间:2015-12-07 14:49:35

标签: java

在学校测试中,我在anonyme内部类中使用了非final变量。 在学校计算机和我的私人计算机上(使用x86 jre1.8.0_45)它正在工作。

然而,在老师笔记本电脑Eclipse上显示错误(变量应该使用final)。他正在使用jre1.8.0.x版本(不知道具体版本)。

为什么它在我的电脑上而不是在他的电脑上工作?

在此代码示例中,在ActionListener的actionPerformed函数中使用了无最终对象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");

            }
        });
    }
}

2 个答案:

答案 0 :(得分:6)

较新的java版本在这个问题上更容忍:它们只要求它们应该是#34;有效的最终版本"。

最后,差异并不大 - 你只能使用你可以用final标记的变量;你可能不会修改它们。

如果你在那个地方,那么你也可以做到#34;真的" final,它无处不在。

顺便说一句,1.8使用新的lambda语法,你可以写得更优雅

button.addActionListener((ActionEvent arg0) -> jLabel.setText("xyz"));

答案 1 :(得分:0)

您可以将监听器定义为匿名类,但作为私有内部类以避免该问题:

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");            
        }

    }
}

通过这种方式,您可以将标签(和按钮,如果需要)传递给侦听器的构造函数,并且可以毫无问题地使用它。