簡體   English   中英

最終局部變量無法分配,因為它是在封閉類型中定義的

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM