无法为java中的"final"变量赋值

ric*_*ick 13 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( );
    }
});
}
Run Code Online (Sandbox Code Playgroud)

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

ban*_*ana 34

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

关于"最终"的警告是误导性的 - 只是编译器告诉你不能从匿名类访问瞬态局部变量.你不能仅仅通过使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());
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 14

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

final int[] c = {0};
...
c[0] = Integer.parseInt(f.getText());
Run Code Online (Sandbox Code Playgroud)

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

  • 我尝试了很多解决方案,只有这个技巧有效.我的变量是在AsyncTask外部自定义类中.+1 (2认同)

T.J*_*der 6

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

对.final变量的整个要点是你只能分配给它们一次,但你试图分配给它两次(一次在初始化设置中0,一次在你的引用行中).从规格:

可以声明变量final.甲final变量可以仅被分配给一次.声明变量final可以作为有用的文档,它的值不会改变,可以帮助避免编程错误.

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

空白final是一个final变量,其声明缺少初始化程序.

一旦一个final变量被分配,它总是包含相同的值.如果final变量包含对对象的引用,则可以通过对对象的操作来更改对象的状态,但该变量将始终引用同一对象.

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

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