13
 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”。谁能告诉我为什么会这样?

4

7 回答 7

34

您已经在函数中声明了c,然后在该函数中创建了一个匿名内部类。这个内部类 ActionListener 在您的函数终止之后仍然存在 - 因此它不能为 c 赋值,因为 c 是函数的本地类。

关于“final”的警告具有误导性——这只是编译器告诉你不能从匿名类访问瞬态局部变量。您不能仅通过将 c 设为 final 来解决问题,因为这将完全阻止对其进行任何分配,但您可以将 c设为 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());
            }
        });
    }
}
于 2012-04-16T12:35:51.147 回答
14

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

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

有关完整的故事,请参阅这篇文章

于 2012-04-16T12:33:24.967 回答
6

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

对。变量的全部意义final在于您只能分配给它们一次,但是您尝试分配给它两次(一次在初始化时将其设置为0,一次在引用的行中)。从规范

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

如果一个final变量被赋值,这是一个编译时错误,除非它在赋值之前被明确地未赋值(第 16 节)。

空白finalfinal其声明缺少初始化程序的变量。

final分配变量后,它始终包含相同的值。如果final变量持有对对象的引用,则对象的状态可能会通过对对象的操作而改变,但变量将始终引用同一个对象。

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

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

于 2012-04-16T12:28:52.937 回答
2

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

于 2012-04-16T12:28:51.237 回答
0

使用final关键字声明变量意味着它的值不能更改。final 变量就像常量

于 2012-04-16T12:28:32.143 回答
0

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

编辑:

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

我相信这是导致编译器发出警告的代码段。你不能c在这堂课中使用...

于 2012-04-16T12:29:48.140 回答
-4

只需final从声明中删除关键字并继续您的程序。作为final关键字意味着值不变。

于 2012-04-16T12:30:20.563 回答