Последняя локальная переменная не может быть назначена, так как она определена во вложенном типе

1

Я знаю, что на это ответили серверные времена, но я не могу найти решение моей проблемы. Я пытаюсь создать очень, очень основную игру для себя, но у меня возникают проблемы с определением переменной "наличные" внутри нажатия кнопки. Мой код:

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);
            }
        }

    });
}
  • 0
    Почему бы не объявить свой финал вне метода? Большинству людей все равно нравится объявлять свои окончательные переменные как публичные переменные. Есть ли конкретная причина, почему вы не можете сделать это?
  • 0
    @DreadHeadedDeveloper Я последовал вашему решению, и оно работает! Однако единственная проблема, с которой я столкнулся, заключается в том, что lblCash теперь не может определить, какие денежные средства находятся на старте, я могу изменить код, но он изменится только после нажатия кнопки. У вас есть решение для этого? Заранее извиняюсь
Показать ещё 1 комментарий
Теги:
variables
int

3 ответа

2
Лучший ответ

Вероятно, вам нужна константа с начальной суммой наличных денег и переменной для баланса наличности (оба определены на уровне класса).

static final int INIT_CASH = 1000000;

int cash = INIT_CASH; // variable intialization
0

Мне кажется, что cash не должны быть final, и вы сделали это final потому что компилятор сказал вам, что вы не можете сказать " cash = cash - ammount потому что переменная cash не была final. Однако сделать его final не будет, потому что вы не можете изменить значение. Так случилось?

В Java, когда метод содержит инструкцию, которая создает анонимный класс (как вы это делали с new ActionListener), он не может ссылаться на локальные переменные метода, если они не являются final. (Это было решение для языка. С# и 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 проще и, вероятно, более уместно.

0

Если вы хотите изменить стоимость наличных денег, вы не должны делать ее окончательной, поскольку она делает ее неизменной или постоянной.

Вы должны сделать переменную cash переменной экземпляра вместо метода local, потому что обычно вы хотите, чтобы он жил больше, чем один вызов метода.

public class Main{
  // instance variable
  int cash = 1000000;

  public Main(){
  // your logic
  }

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню