final
が以下のコード間でどのような違いをもたらしますか。引数をfinal
として宣言することに利点はありますか。
public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){
return ....
}
public String changeTimezone(final Timestamp stamp, final Timezone fTz,
final Timezone toTz){
return ....
}
正式なメソッドパラメータはローカル変数であるため、finalとして宣言されている場合にのみ、内部の匿名クラスからアクセスできます。
これにより、メソッド本体で別のローカルfinal変数を宣言する必要がなくなります。
void m(final int param) {
new Thread(new Runnable() {
public void run() {
System.err.println(param);
}
}).start();
}
最終キーワードの最終単語 からの抽出
最終パラメータ
次のサンプルでは、最終パラメーターを宣言しています。
public void doSomething(final int i, final int j)
{
// cannot change the value of i or j here...
// any change would be visible only inside the method...
}
ここでfinalは、2つのインデックスiとjがメソッドによって誤ってリセットされないようにするために使用されます。これは、パラメーターの値を誤って変更する潜行性のバグから保護するための便利な方法です。一般的に、このメソッドのエラーから保護するには、短いメソッドの方が適していますが、最終的なパラメーターはコーディングスタイルに追加すると便利です。
最終パラメーターはメソッドシグネチャの一部とは見なされず、メソッド呼び出しの解決時にコンパイラーによって無視されることに注意してください。メソッドのオーバーライド方法に影響を与えずに、パラメーターをfinalとして宣言することも、宣言しないこともできます。
最後は、変数に新しい値を割り当てることを防ぎます。これは、タイプミスを見つけるのに役立ちます。様式的には、受け取ったパラメーターを変更せずに保持し、ローカル変数にのみ割り当てることができます。そのため、finalはそのスタイルを強制するのに役立ちます。
パラメーターにfinalを使用することをほとんど覚えていないことを認めなければなりません。
public int example(final int basicRate){
int discountRate;
discountRate = basicRate - 10;
// ... lots of code here
if ( isGoldCustomer ) {
basicRate--; // typo, we intended to say discountRate--, final catches this
}
// ... more code here
return discountRate;
}
大きな違いはありません。それはあなたが書くことができないことを意味します:
stamp = null;
fTz = new ...;
しかし、あなたはまだ書くことができます:
stamp.setXXX(...);
fTz.setXXX(...);
メンテナンスプログラマーへの主なヒントは、メソッドの途中でパラメーターに新しい値を割り当てないというヒントです。この値は明らかではないため、混乱を招く可能性があります。
Javaのパラメータ/変数に使用されるときのfinalキーワードは、参照をfinalとしてマークします。オブジェクトを別のメソッドに渡す場合、システムは参照変数のコピーを作成し、新しい参照に最終的なマークを付けることにより、再割り当てから保護します。
このメソッドの本体では、final
キーワードにより、これらの場合に引数参照が誤って再割り当てされ、コンパイルエラーが発生するのを防ぎます(ほとんどのIDEはすぐに文句を言います)。可能であればいつでも一般的にfinal
を使用すると速度が上がると主張する人もいますが、最近のJVMではそうではありません。
Javaのコンストラクトは、コントラクトを定義し、それに固執するのに役立ちます。同様の議論はここにあります。 http://c2.com/cgi/wiki?JavaFinalConsideredEvil =
ところで-(twikiが言うように)良いプログラミングの原則に従っている場合、引数を最終としてマークすることは一般的に冗長であり、完了した引数の参照を再割り当て/再定義することができます。
最悪の場合、引数参照を再定義しても、参照のみが渡されるため、関数に渡される実際の値には影響しません。
-過去((Java 8 :-)の前)
「最終」キーワードの明示的な使用は、内部匿名クラスのメソッド変数のアクセシビリティに影響しました。
-現代の(Java 8+)言語では、そのような使用法は必要ありません:
Javaは「効果的に最終的な」変数を導入しました。コードが変数の値の変更を意味しない場合、ローカル変数とメソッドパラメーターは最終的なものと見なされます。そのため、Java8 +でこのようなキーワードが表示された場合、それは不要であると想定できます。 「実質的に最終」の導入により、ラムダを使用するときに入力するコードが少なくなります。
私は一般的に変数とフィールドを最終的にマークすることについて話している-メソッドの引数だけに適用されるわけではない。 (メソッド/クラスの最終的なマーキングはまったく別のものです)。
それはあなたのコードの読者/将来のメンテナーに好意的です。変数の意味のある名前と一緒に、問題の変数が何を表しているかを見る/理解することは、コードの読者にとって有用で安心です-そして、同じスコープ内の変数を見るたびに意味が変わらないことを読者に安心させます同じため、(s)彼は頭をひっかいてすべてのコンテキストで変数が何を意味するのかを常に把握する必要はありません。変数の「再利用」の乱用が多すぎて、短いコードスニペットでも理解しにくくなっています。