繁体   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