web-dev-qa-db-ja.com

javaの "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());」という行です。 「最終的な変数に値を割り当てることができません」というエラーが発生します。 Wordのfinalを宣言から削除し、それを「int c」と同じようにすると、同じ行で「ローカル変数cはクラス内からアクセスできません。finalと宣言する必要があります」というエラーが発生します。なぜこれが起こっているのですか?

13
rick

関数内でcを宣言し、その関数内に匿名の内部クラスを作成しました。この内部クラスであるActionListenerは、関数が終了した後も存続します。cは関数に対してローカルであるため、cに値を割り当てることができません。

「最終」に関する警告は誤解を招くものです。これは、匿名クラスから一時的なローカル変数にアクセスできないことをコンパイラに通知するだけです。 cをfinalにするだけでは問題を解決できません。cを割り当てることはできなくなりますが、代わりに、cをpushButtonActionPerformedクラスのin instance member inにすることができます。このようなもの:

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

私は理由をスキップして解決策に切り込みます:使用

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

詳細は この投稿 を参照してください

14
Marko Topolnik

しかし、行 "c = Integer.parseInt(f.getText());" 「最終的な変数に値を割り当てることができません」というエラーが発生する

正しい。 final変数の要点は、変数に1回しか割り当てられないが、2回割り当てようとしていることです(初期化設定で0に設定し、引用符で囲まれた行で1回) )。 仕様 から:

変数はfinalと宣言できます。 final変数は、一度だけ割り当てることができます。変数finalを宣言すると、その値が変更されず、プログラミングエラーを回避するのに役立つドキュメントとして役立ちます。

final変数が割り当ての直前に明確に割り当てられていない限り(§16)、割り当てられていない限り、これはコンパイル時エラーです。

空白のfinalは、宣言に初期化子がないfinal変数です。

final変数が割り当てられると、常に同じ値が含まれます。 final変数がオブジェクトへの参照を保持している場合、オブジェクトの状態はオブジェクトの操作によって変更される可能性がありますが、変数は常に同じオブジェクトを参照します。

(私のものではなく、それらの強調)

メソッドの変数のcに保存している状態を追跡する代わりに、作成している匿名ActionListenerのインスタンスのデータメンバーで追跡します。

6
T.J. Crowder

これがキーワードfinalがJavaに存在する理由です。変数は最終的なものです。つまり、その値は変更できません。値を変更する必要がある場合は、変数を最終としてマークしないでください。

2
AlexR

変数がfinalキーワードで宣言されている場合、その値は変更できません。最終的な変数はconstantsのようになります

0
Chandra Sekhar

finalは、「変数」を定数にします。変更することはできません。最後のキーワードを削除した後にコンパイラが警告を表示する理由については、コード全体を確認する必要があります...

編集:

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

これは、コンパイラが警告を発する原因となるコードのセグメントだと思います。このクラスではcを使用できません...

0
apnorton