Вопрос по swing, final, java – не может присвоить значение «окончательной» переменной в Java

13
<code> private void pushButtonActionPerformed(java.awt.event.ActionEvent evt)
{
    final int c=0;
    final JDialog d=new JDialog();
    JLabel l=new JLabel("Enter the Element :");
    JButton but1=new JButton("OK");
    JButton but2=new JButton("Cancel");
    final JTextField f=new JTextField(10);
    JPanel panel = new JPanel();
    but1.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            c=Integer.parseInt(f.getText());
            d.setVisible(false);
            d.dispose( );
        }
     });
but2.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
        d.setVisible(false);
        d.dispose( );
    }
});
}
</code>

Я использую NetBeans 7.1.1. Это мой код, который я объявил здесь. как & quot; final int & quot; но строка & quot; c = Integer.parseInt (f.getText ()); & quot; я получаю сообщение об ошибке "не могу присвоить значение конечной переменной". Если я удаляю слово final из объявления и делаю его так же, как & quot; int c & quot; затем в той же строке я получаю сообщение об ошибке «локальная переменная c не может быть доступна из класса; необходимо объявить final». Кто-нибудь может сказать мне, почему это происходит?

@MarkoTopolnik Нет, этот тег помечен как «качели» :П Limited Atonement
Duplicate Marko Topolnik

Ваш Ответ

7   ответов
0

переменная объявлена сfinal Ключевое слово означает, что его значение не может быть изменено. Конечная переменная, какconstants

Это не проблема OP. Он не может удалить финал, поскольку он мутирует в локальном классе.
6

but the line "c=Integer.parseInt(f.getText());" i am getting an error "cannot assign a value to a final variable

Правильно. Весь смыслfinal переменными является то, что вы можете назначить их только один раз, но вы пытаетесь назначить их дважды (один раз в инициализации, установив его0однажды в вашей цитируемой строке). Отспецификация:

A variable can be declared final. A final variable may only be assigned to once. Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.

It is a compile-time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.

A blank final is a final variable whose declaration lacks an initializer.

Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.

(Their emphasis, not mine.)

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

Создайте состояние, в котором вы пытаетесь отследить что-то, что вы отслеживаете в своем анонимном экземпляре ActionListener, а не в переменной в окружающей функции (я обновил ответ, чтобы сказать это).
так как решить проблему? rick
34

Вы получилиc объявлен в функции, а затем вы создали анонимный внутренний класс в этой функции. Этот внутренний класс, ActionListener, сохраняется после того, как ваша функция завершает работу, поэтому он не может присваивать значения c, поскольку c является локальным для функции.

Предупреждение о "окончательном" вводит в заблуждение - это просто компилятор, который говорит вам, что вы не можете получить доступ к временным локальным переменным из анонимного класса. Вы не можете решить проблему, просто сделав c final, так как это вообще предотвратит любое присвоение ей, но вы можете сделать cinstance member вместо этого используется класс pushButtonActionPerformed. Что-то вроде этого:

class Something
{
    int c;

    private void pushButtonActionPerformed(java.awt.event.ActionEvent evt)
    {
        JButton but1=new JButton("OK");
        but1.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                c=Integer.parseInt(f.getText());
            }
        });
    }
}
Ваш пример кода неверен, потому что у вас естьnot сделал закрытие, поэтому все экземпляры анонимного класса будут иметь один и тот же int.
Помимо ненависти Марко выше, это было отличным объяснением и решило мою проблему. два больших пальца вверх
Утверждение, что «вы не можете получить доступ к временным локальным переменным из анонимного класса» ложно Также неверно, что конечная переменная не может быть назначена. Если бы это было правдой, не было бы такой вещи как финальная переменная, поскольку она была бы бесполезна. На самом деле происходит то, чтоclosure создан, чтоcloses over переменная в области объявления анонимного класса. У Java есть только то ограничение, что вы можете закрывать только финальные переменные. Это для обеспечения безопасности потока.
2

Это причина того, что ключевое словоfinal существует в Java. Переменная является окончательной, то есть ее значение не может быть изменено. Если вам нужно изменить значение, не помечайте переменную как окончательную.

Это не решает проблему OP, поскольку он изменяет var внутри локального класса.
0

final делает "переменную" константа - вы не можете ее изменить. Что касается того, почему компилятор выдает вам предупреждения после того, как вы удалите ключевое слово final, нам нужно увидеть весь код ...

РЕДАКТИРОВАТЬ:

 but1.addActionListener(new ActionListener()
 {
     public void actionPerformed(ActionEvent e)
     {
         c=Integer.parseInt(f.getText());
         d.setVisible(false);
         d.dispose( );
     }
  });

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

14

Я пропущу причины и перейду к решению: используйте

final int[] c = {0};
...
c[0] = Integer.parseInt(f.getText());

Для полной истории обратитесь кэта почта

Я пробовал так много решений, только этот трюк сработал. Моя переменная была во внешнем пользовательском классе AsyncTask. +1
Причина в том, что, хотя адрес массива c [] является принудительным постоянным с последним ключевым словом, его содержимое не является: они изменчивы. Голосуй от меня.
-4

Просто удалитеfinal Ключевое слово из декларации и продолжить вашу программу. Какfinal Ключевое слово означает, что значение не изменилось.

Не отвечает на вопрос - OP заявил, что он получает еще одну ошибку, когда удаляет final.

Похожие вопросы