最終的なローカル変数を使用するユーザビリティがあるのではないかと思っていました。とにかく、継承が発生しても変数は上書きされません。たとえば、次のような簡単なコード
public static void main(String args[]) {
final String data = "Hello World!";
System.out.println(data);
}
この例は非常に単純なものであり、関連するコードではないかもしれませんが、質問はより一般的です。同じ機能自体で編集することはできません。
まず、変数が「オーバーライド」される部分-final
には、2つの非常に異なる意味があります。クラスとメソッドの場合、それは継承に関するものです。変数については、読み取り専用であることです。
最終的なローカル変数には、ローカル(通常は匿名)内部クラスで使用できる重要な機能が1つあります。非最終ローカル変数は使用できません。私の経験では、これがローカル変数のfinal
の主な用途です。
public void foo() {
final String x = "hello";
String y = "there";
Runnable runnable = new Runnable() {
@Override public void run() {
System.out.println(x); // This is valid
System.out.println(y); // This is not
}
};
runnable.run();
}
スタイルの問題として、一部の人々は、ローカル内部クラスで変数をキャプチャするnotであっても、final
を使用することを好むことに注意してください。確かにfinal
がデフォルトであることに満足していますが、「非最終」の修飾子は異なりますが、どこにでも修飾子を明示的に追加すると気が散りすぎます。
最終的なローカル変数には匿名の内部サブクラスからアクセスできますが、非最終的なローカル変数にはアクセスできません。
はい、使いやすさは次のとおりです。ローカルのfinal変数は、メソッド内部クラスからアクセスできます。ローカル変数はスタック上に存在し、メソッドの存続期間のみ存在するため、内部クラスオブジェクトはより長く存続するため、内部クラスは最終的なローカル変数にアクセスできません。ただし、変数がfinalになると、内部クラスは値が変更されないことを確認して、最終的なローカル変数のプライベートコピーを使用できるようにします。
Jon Skeetの完璧な答えですが、最終的な変数には別の(小さな)利点があります。
コンパイラーは、最終変数が一度だけ設定されるようにします。
変数を初期化する必要があり、値の計算が複雑だとしましょう(if-then-else内の複数のif-then-else)。何らかの条件で変数を初期化しない(または2回初期化する)コードを作成できます。もちろん、これはバグです。変数をfinalにすると、コンパイラはfinal変数が1回だけ設定されていることを確認できます。バグがあるかどうかをすぐに知ることができます。
私が言ったように、ほとんど利点はありませんが、それでも便利です。
はい、通常使用できる小さなサンプルがあります-
スニペット:
final Boolean data = Boolean.TRUE;
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (data ) {
....
}
}
});
匿名の内部クラスでの使用例。内部変数内でローカル変数を使用する場合は、final
を作成する必要があります。
Javaでの最終ローカル変数の使用
final
フィールド、パラメーター、およびローカル変数は、読み取り専用(状態ではなくオブジェクトのIDを意味します)です。
final
キーワードを使用して読みやすくし、変更されないようにするか、次のような匿名クラスで使用できます。
final String s = "hi";
new Thread(new Runnable() {
@Override
public void run() {
// can use s variable here
}
}).start();
他のプログラマーに、それを書いた人は誰でもdataの値が一度割り当てられても変わらないことを知っていたことを伝えます。私の意見では、特にパラメーター変数をfinalとして宣言するのは良い習慣です。