[英]The final local variable cannot be assigned, since it is defined in an enclosed type
I know this has been answered serveral times, but I can't seem to find a solution to my problem. 我知道这已经在服务器时代得到了回答,但是我似乎找不到解决我问题的方法。 I'm trying to create a very, very basic game for myself but I am having issues defining the variable "cash" inside of the button click. 我正在尝试为自己创建一个非常非常基础的游戏,但是在单击按钮内部定义变量“ cash”时遇到问题。 My code is: 我的代码是:
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);
}
}
});
}
You probably need a constant with initial cash amount and a variable for cash balance (both defined on a class level). 您可能需要一个带有初始现金量的常量和一个现金余额变量(均在类级别上定义)。
static final int INIT_CASH = 1000000;
int cash = INIT_CASH; // variable intialization
If you want the value of cash to be changing you should not make it final as it makes it unchanging or constant. 如果您希望现金的价值在变化,则不应将其定为最终货币,因为它会使货币不变或不变。
You should make the cash variable an instance variable instead of method local, because usually you want it to live more than the one method call. 您应该使cash变量成为实例变量,而不是局部方法,因为通常您希望它活得比一个方法调用更多。
public class Main{
// instance variable
int cash = 1000000;
public Main(){
// your logic
}
}
It appears to me that cash
should not be final
, and you made it final
because the compiler told you that you couldn't say cash = cash - ammount
because the variable cash
was not final
. 在我看来, cash
不应该是final
,您之所以做到了final
是因为编译器告诉您不能说cash = cash - ammount
因为可变cash
不是final
。 However, making it final
won't work because then you can't modify the value. 但是,将其定为final
将行不通,因为那样便无法修改该值。 Is that what happened? 那是怎么回事?
In Java, when a method contains a statement that creates an anonymous class (as you've done with new ActionListener
), it can't refer to the method's local variables, unless they are final
. 在Java中,当方法包含创建匿名类的语句时(就像您对new ActionListener
所做的那样),除非它们是final
,否则它无法引用该方法的局部变量。 (This was a language design decision. C# and JavaScript, which have similar constructs, don't have this restriction.) Here you have a constructor, which isn't really a method, but it behaves like a method. (这是一种语言设计决策。具有类似构造的C#和JavaScript不受此限制。)在这里,您有一个构造函数,它实际上不是方法,但其行为类似于方法。 There are two ways around this: 有两种解决方法:
1) Make the variable an instance field, instead of a local variable. 1)将变量设为实例字段,而不是局部变量。 Thus, you'd say int cash = 1000000
outside the constructor. 因此,您可以在构造函数之外说int cash = 1000000
。
This is an appropriate solution when you could only have one such variable per object. 当每个对象只能有一个这样的变量时,这是一个合适的解决方案。 It's also appropriate in your case, since you have cash
inside a constructor. 由于您在构造函数中有cash
,因此这也很适合您。 The constructor can't be called more than once per object, so there can be only one cash
for an object. 每个对象最多只能调用一次构造函数,因此一个对象只能使用一次cash
。
However, there are cases where this won't work, where the variable is declared inside a method rather than a constructor. 但是,在某些情况下,此变量将无法使用,即在方法而不是构造函数中声明变量。 Suppose you have a method that creates a new button, and it's possible that multiple buttons will be created with multiple calls to this method, and each new button will have its own listener, each with its own variable that it modifies. 假设您有一个创建新按钮的方法,并且可能会通过对该方法的多次调用来创建多个按钮,并且每个新按钮都有自己的侦听器,每个侦听器都有自己修改的变量。 Now having just one instance variable for the object won't work. 现在只有对象的一个实例变量将不起作用。 So another way to work around the final
problem is: 因此,解决final
问题的另一种方法是:
2) Make the variable a field inside some other object. 2)使变量成为其他对象内部的字段。 You could declare a very simple class that just holds a cash
field: 您可以声明一个非常简单的类,只包含一个cash
字段:
private static class Wallet { // a Wallet holds cash, hee hee hee
public int cash;
public Wallet(int cash) { this.cash = cash; }
}
and in your method 和你的方法
final Wallet wallet = new Wallet(1000000);
Now the anonymous class can refer to wallet
, because it's final
. 现在,匿名类可以引用wallet
,因为它是final
。 But only the reference to the Wallet
object is final, not the fields; 但是只有对Wallet
对象的引用是最终的,而不是字段。 so the anonymous class can still modify wallet.cash
. 因此匿名类仍可以修改wallet.cash
。 (Another way to create an object is to make it an array of one element. Declaring a new class is more readable, in my opinion.) (创建对象的另一种方法是使它成为一个元素的数组。我认为声明新类更易读。)
I'm mentioning this so that you know how to solve the problem when it comes up--and it does come up fairly frequently. 我要说的是,这样一来,您就知道如何解决问题-而且确实确实经常出现。 However, in your case, solution 1 is simpler and probably more appropriate. 但是,根据您的情况,解决方案1更简单并且可能更合适。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.