无法为java中的“final”变量赋值

时间:2012-04-16 12:27:15

标签: java swing final

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

我正在使用netbeans 7.1.1。这是我的代码,我已将'c'声明为“final int”,但行“c = Integer.parseInt(f.getText());”我收到错误“无法为最终变量赋值”。如果我从声明中删除单词final并将其作为“int c”,那么在同一行中我得到一个错误“无法从类中访问局部变量c;需要声明为final”。谁能告诉我为什么会这样呢?

7 个答案:

答案 0 :(得分:34)

你在一个函数中声明了 c ,然后你在该函数中创建了一个匿名内部类。这个内部类ActionListener会在函数终止时间之后持续存在 - 因此它无法为c赋值,因为c是函数的本地值。

关于“最终”的警告具有误导性 - 只是编译器告诉您无法从匿名类访问瞬态局部变量。你不能仅仅通过使c final成为问题来解决问题,因为这会阻止对它的任何赋值,但是你可以使用类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());
            }
        });
    }
}

答案 1 :(得分:14)

我会跳过原因并切入解决方案:使用

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

有关完整报道,请参阅this post

答案 2 :(得分:6)

  

但行“c = Integer.parseInt(f.getText());”我收到错误“无法为最终变量赋值

右。 final变量的全部内容是您只能分配给它们一次,但是您尝试分配两次(一次在初始化设置中为0,一次在引用行中) 。来自the specification

  

变量可以声明为finalfinal变量只能分配一次。声明变量final可以作为有用的文档,它的值不会改变,可以帮助避免编程错误。

     

如果分配final变量,则为编译时错误,除非在分配之前它是明确未分配的(§16)。

     

空白finalfinal变量,其声明缺少初始值设定项。

     

分配final变量后,它始终包含相同的值。如果final变量包含对对象的引用,则对象的状态可能会被对象上的操作更改,但该变量将始终引用同一对象。

(他们的重点,不是我的。)

不是尝试跟踪您在c中存储在方法中的变量中的状态,而是在您正在创建的匿名ActionListener实例中的数据成员中跟踪它。 / p>

答案 3 :(得分:2)

这就是java中存在关键字final的原因。变量是最终的,即它的值不能改变。如果必须更改值,请不要将变量标记为final。

答案 4 :(得分:0)

使用 final 关键字声明变量意味着无法更改其值。最终变量类似于常量

答案 5 :(得分:0)

final使“变量”成为常数 - 你无法改变它。至于为什么编译器在你删除final关键字后给你警告,我们需要查看整个代码......

编辑:

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

我相信这是导致编译器触发警告的代码段。您无法在此课程中使用c ...

答案 6 :(得分:-4)

只需从声明中删除final关键字,然后继续执行您的计划。由于final关键字表示该值未更改。