Javaの最終変数とは何ですか? たとえばfinal int temp;
、関数で記述した場合、final キーワードの意味は何ですか?
また、いつ final 変数を (クラス変数と関数変数の両方として) 使用したいですか?
同期ブロック内の変数を final と宣言する必要があるのはなぜですか?
3 に答える
最終変数と同期されたコードブロックには共通点があります...非最終変数を宣言しa
てから書き込むとsynchronized (a) { System.out.println('xxx'); }
、少なくともNetBeansでは「非最終フィールドでの同期」という警告が表示されます。
final 以外のフィールドで同期してはいけないのはなぜですか? フィールド値が変更される可能性がある場合、異なるスレッドが異なるオブジェクト (フィールドの異なる値) で同期している可能性があるため、同期がまったくない可能性があります (すべてのスレッドが同時に同期ブロックに入る可能性があります)。
final 以外のフィールドでの同期によって引き起こされる実際の問題の例については、こちらを参照してください: http://forums.sun.com/thread.jspa?threadID=5379204
基本的に、値を変更できないことを意味します。インスタンス変数の場合、コンストラクターで (または変数初期化子を使用して) 最終変数を 1 回 (そして 1 回だけ) 割り当てる必要があります。同期はかなり直交する概念です。
ローカル変数を finalにする主な理由は、匿名の内部クラスで使用できるようにするためです...これは、同期ブロック内にあることとは関係ありません。
確かに、最終変数は不変クラスに役立ちます-そして不変性はマルチスレッド環境での生活を楽にします-しかし、それは私が考えることができる2つの間の唯一の関係です...
編集: Wildwezyr のコメントは、同期している変数を変更しないという点で理にかなっています。彼が与えた理由からすれば、それは危険だろう。それが「同期ブロックの変数」という意味ですか?
Jon Skeet が言ったことに加えて、値は変更できませんが、内容は変更される可能性があります。
final Integer one = new Integer(1);
...
one = new Integer(2); // compile error
final List list = new ArrayList();
...
list = new ArrayList(); // compile error
list.add(1); // Changes list, but that's fine!
また、final と static final は同じではないことに注意してください。final はインスタンスのスコープ内にありますが、 static final はクラスのすべてのインスタンスで同じです (他の言語ではこれは定数と呼ばれます)。
個人的には、ソフトウェアを動作させるために絶対に必要ではない場合でも、final の利点は意味論的な意味にあると思います。コンパイラーとそのコードに取り組んでいる次の人に、この変数は変更するつもりがなく、変更しようとするとバグが発生する可能性があることを伝える可能性があります。