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;