![](/img/trans.png)
[英]Java: the final local variable cannot be assigned, since it was defined in an enclosing type
[英]The final local variable cannot be assigned, since it is defined in an enclosed type
我知道这已经在服务器时代得到了回答,但是我似乎找不到解决我问题的方法。 我正在尝试为自己创建一个非常非常基础的游戏,但是在单击按钮内部定义变量“ cash”时遇到问题。 我的代码是:
public Main() {
final int cash = 1000000;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblCash = new JLabel("Cash: " + cash);
lblCash.setBounds(10, 11, 166, 14);
contentPane.add(lblCash);
JButton btnStake = new JButton("STAKE");
btnStake.setBounds(258, 227, 166, 23);
contentPane.add(btnStake);
final JLabel lblwol = new JLabel("");
lblwol.setBounds(10, 115, 414, 14);
contentPane.add(lblwol);
sa = new JTextField();
sa.setBounds(10, 228, 238, 20);
contentPane.add(sa);
sa.setColumns(10);
btnStake.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String stringAmmount = sa.getText().toString();
int ammount = Integer.parseInt(stringAmmount);
sa.setText("");
double comp = Math.random();
if (comp < 0.5){
lblwol.setText("Congratulations, you have won: " + ammount);
cash = cash - ammount;
} else {
lblwol.setText("Sorry, you have lost: " + ammount);
}
}
});
}
您可能需要一个带有初始现金量的常量和一个现金余额变量(均在类级别上定义)。
static final int INIT_CASH = 1000000;
int cash = INIT_CASH; // variable intialization
如果您希望现金的价值在变化,则不应将其定为最终货币,因为它会使货币不变或不变。
您应该使cash变量成为实例变量,而不是局部方法,因为通常您希望它活得比一个方法调用更多。
public class Main{
// instance variable
int cash = 1000000;
public Main(){
// your logic
}
}
在我看来, cash
不应该是final
,您之所以做到了final
是因为编译器告诉您不能说cash = cash - ammount
因为可变cash
不是final
。 但是,将其定为final
将行不通,因为那样便无法修改该值。 那是怎么回事?
在Java中,当方法包含创建匿名类的语句时(就像您对new ActionListener
所做的那样),除非它们是final
,否则它无法引用该方法的局部变量。 (这是一种语言设计决策。具有类似构造的C#和JavaScript不受此限制。)在这里,您有一个构造函数,它实际上不是方法,但其行为类似于方法。 有两种解决方法:
1)将变量设为实例字段,而不是局部变量。 因此,您可以在构造函数之外说int cash = 1000000
。
当每个对象只能有一个这样的变量时,这是一个合适的解决方案。 由于您在构造函数中有cash
,因此这也很适合您。 每个对象最多只能调用一次构造函数,因此一个对象只能使用一次cash
。
但是,在某些情况下,此变量将无法使用,即在方法而不是构造函数中声明变量。 假设您有一个创建新按钮的方法,并且可能会通过对该方法的多次调用来创建多个按钮,并且每个新按钮都有自己的侦听器,每个侦听器都有自己修改的变量。 现在只有对象的一个实例变量将不起作用。 因此,解决final
问题的另一种方法是:
2)使变量成为其他对象内部的字段。 您可以声明一个非常简单的类,只包含一个cash
字段:
private static class Wallet { // a Wallet holds cash, hee hee hee
public int cash;
public Wallet(int cash) { this.cash = cash; }
}
和你的方法
final Wallet wallet = new Wallet(1000000);
现在,匿名类可以引用wallet
,因为它是final
。 但是只有对Wallet
对象的引用是最终的,而不是字段。 因此匿名类仍可以修改wallet.cash
。 (创建对象的另一种方法是使它成为一个元素的数组。我认为声明新类更易读。)
我要说的是,这样一来,您就知道如何解决问题-而且确实确实经常出现。 但是,根据您的情况,解决方案1更简单并且可能更合适。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.