Java 为什么我突然需要将变量声明为";“最后的”;将ActionListener添加到按钮时?

Java 为什么我突然需要将变量声明为";“最后的”;将ActionListener添加到按钮时?,java,jframe,jbutton,actionlistener,final,Java,Jframe,Jbutton,Actionlistener,Final,可能重复: 这是我为班级制作的“随机数学游戏”的代码: package RandomMathGame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class RandomMathGame { public static void main(String[] args) { RandomProblemGene

可能重复:

这是我为班级制作的“随机数学游戏”的代码:

package RandomMathGame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class RandomMathGame {

    public static void main(String[] args) {
        RandomProblemGenerator randomProblems = new RandomProblemGenerator(10);
        final int numberProblems = 10;
        int correctScore = 0;
        JPanel panel = new JPanel();
       int answer;
        int correctAnswer;
        JLabel[] mathProblems = new JLabel[numberProblems];
        final JTextField[] mathAnswers = new JTextField[numberProblems];
        JLabel[] correctYesNo = new JLabel[numberProblems];
        final JLabel score = new JLabel(correctScore + "/10");
        JButton submit = new JButton("Submit");
        for (int i = 1; i <= numberProblems; i++)
        {
            final int X = randomProblems.createNumberX();
            final int Y = randomProblems.createNumberY();

            mathProblems[i] = new JLabel("" + X + " * " + Y + " = ");
            mathAnswers[i] = new JTextField();


             answer = Integer.parseInt(mathAnswers[i].getText());
             correctAnswer = X * Y;

            if (answer == correctAnswer)
            {
                correctYesNo[i] = new JLabel("Correct answer; good job!");
                correctScore = correctScore + 1;
            }
            else
            {
               correctYesNo[i] = new JLabel("Incorrect answer; try again!");

            }
             panel.add(mathProblems[i]);
             panel.add(mathAnswers[i]);
             panel.add(correctYesNo[i]);
            }
      submit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                score.setText("Score: " + correctScore + "/10");
            }
        });



        panel.add(submit);
        panel.add(score);

        JFrame gameFrame = new JFrame();
        gameFrame.setTitle("Random Math Game");
        gameFrame.setSize(150, 150);
        gameFrame.setVisible(true);
        gameFrame.setContentPane(panel);



        }
  }
打包游戏;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.*;
公共类随机数学游戏{
公共静态void main(字符串[]args){
RandomProblemGenerator RandomProblemGenerator=新的RandomProblemGenerator(10);
最终整数问题=10;
int校正分数=0;
JPanel面板=新的JPanel();
int答案;
正确答案;
JLabel[]mathProblems=新JLabel[numberProblems];
最终JTextField[]mathAnswers=新JTextField[numberProblems];
JLabel[]correctYesNo=新JLabel[numberProblems];
最终JLabel分数=新JLabel(正确分数+“/10”);
JButton submit=新JButton(“提交”);

对于Java中的(inti=1;i,如果要从局部类中访问局部变量(

是一个新的本地匿名类) 变量必须声明为final

没有
final
修饰符,局部类无法访问封闭方法的局部变量 例如:

public class Main {
    private int b=5;
    public void bla() {
    int a = 5;
    ActionListener al = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            a = 4; // Error. a must be final
            b = 5; // OK!
        }
    };
  }
}

您的问题的一个可能解决方案是使用在任何方法之外声明的变量(上例中的b)

要将局部变量传递给匿名类,它必须是final-这是Java语言的一部分。现在,当一个基元变量是final时,您不能修改它,因此在生成
correctScore
final时会遇到问题

解决方法是在调用
addActionListener
之前使用临时变量:

final int temp = correctScore;
并在
actionPerformed
方法中使用该
temp
变量


请注意,当您这样做时,对correctScore的任何未来更改都不会反映在temp的值中。

您收到该消息,因为您已声明JLabel score为最终值。您不能使用非最终变量为最终变量设置值。我不知道您为什么要将score设置为最终值。请删除它决赛


编辑:我在第一次阅读时忽略了correctScore是一个函数变量。如果你把它作为一个类变量,我想你的许多问题都会消失。

如所写,那不是真的。我总是从封闭类访问非最终变量,就像这样:ActionListener更新控件中的值。可能有一个piece您遗漏了这一点,这将使这一陈述成为事实。抱歉,我遗漏了这一点。类变量,可以访问(即成员-私有、公共等)。包含匿名类的方法的局部变量,必须是最终的。编辑我的答案
final int temp = correctScore;