[英]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.