57

Java では、ローカル変数とメソッド パラメータを final キーワードで修飾できます。

public static void foo(final int x) {
  final String qwerty = "bar"; 
}

これを行うと、メソッドの本体で x と qwerty を再割り当てできなくなります。

このプラクティスは、一般的にプラスと見なされる不変性の方向にコードを微調整します。ただし、「最終」がいたるところに表示されてコードが乱雑になる傾向もあります。Java のローカル変数とメソッド パラメータの final キーワードについてどう思いますか?

4

12 に答える 12

53

適切な場合はいつでも、これを実行するようにしてください。「誤って」値を変更しようとしたときに警告を表示するだけでなく、クラスファイルの最適化につながる情報をコンパイラに提供します。これは、Robert Simmons、Jrによる本「HardcoreJava」のポイントの1つです。実際、この本は、最適化を促進し、論理エラーを防ぐために、finalの使用に第2章のすべてを費やしています。PMDやEclipseの組み込みSAなどの静的分析ツールは、このような理由でこの種のケースにフラグを立てます。

于 2008-11-25T09:15:10.557 に答える
27

個人的な意見ですが、時間の無駄です。視覚的な混乱と追加された冗長性は、それだけの価値がないと私は信じています。

私は、誤って変数を再割り当てしたことは一度もありません (これはオブジェクトを不変にするわけではなく、変数への別の参照を再割り当てできないことを意味します)。

もちろん、それはすべて個人的な好みです;-)

于 2008-11-25T04:22:47.387 に答える
8

パラメータを finalにすると、メソッド内の任意の場所で使用される値が、渡された値を参照することが保証されます。それ以外の場合は、特定の場所の上にあるすべてのコードを頭の中で解析して、その時点でのパラメーターの値を知る必要があります。

したがって、 final を使用しないと、それだけでコードが読みにくくなり、保守しにくくなります:)

最終的なローカル変数は意図に依存し、私の観点ではそれほど重要ではありません。何が起こるかによります。

于 2009-08-30T08:24:06.513 に答える
6

ローカル変数の場合、私はこれを避ける傾向があります。これは視覚的な混乱を引き起こしますが、一般的には必要ありません。関数は十分に短くするか、単一の影響に焦点を当てて、修正すべきではないものを変更していることをすぐに確認できるようにする必要があります。

マジック ナンバーの場合は、コードではなく定数のプライベート フィールドとして配置します。

私は必要な状況でのみ final を使用します (例: 値を匿名クラスに渡す)。

于 2008-11-25T04:35:26.690 に答える
5

Java の「参照渡し」動作の (時折) 紛らわしい性質のため、私はパラメーター var のファイナライズに完全に同意します。

ローカル変数のファイナライズは、やややり過ぎのようです。

于 2008-11-25T04:27:23.897 に答える
3

はい、そうします。

読みやすさについてです。変数が 1 回だけ割り当てられることがわかっていると、プログラムの可能な状態について簡単に推論できます。

適切な代替手段は、パラメーターが割り当てられたとき、または変数 (ループ変数以外) が複数回割り当てられたときに、IDE 警告をオンにすることです。

于 2008-12-03T20:29:20.727 に答える
2

少し混乱しますが、置く価値はありfinalます。Eclipse などの Ides は、finalそうするように構成すると、自動的に を配置できます。

于 2010-10-03T23:59:54.753 に答える
2

finalこれらのパラメーターを匿名クラスに渡したい場合は、ローカル変数とメソッドパラメーターを作成することが不可欠です。たとえば、匿名スレッドをインスタンス化し、run() メソッドの本体でそれらのパラメーターにアクセスしたい場合などです。

それとは別に、コンパイラの最適化によるパフォーマンスの向上に関するパフォーマンスの利点については確信が持てません。最適化するかどうかは、特定のコンパイラの実装次第です...

...を使用してパフォーマンス統計を知ることは良いことfinalです...

于 2010-10-04T00:12:38.083 に答える
2

final には 3 つの正当な理由があります。

  • コンストラクターによって設定されたインスタンス変数は不変になるだけです
  • オーバーライドされないメソッドは最終的なものになり、デフォルトではなく、実際の理由でこれを使用します
  • メソッド内の無名クラスで使用されるローカル変数またはパラメーターは、final である必要があります

メソッドと同様に、ローカル変数とパラメーターは final と宣言する必要はありません。他の人が前に言ったように、これによりコードが乱雑になり、コンパイラのパフォーマンスを最適化するための労力がほとんどなくなり、コードが読みにくくなります。これは、ほとんどのコードフラグメントの本当の理由ではありません。

于 2008-11-25T07:33:50.637 に答える
0

ローカル変数が再割り当てされない、または再割り当てされるべきではないと思われる場合は、ここでローカル変数に対してそれを行います。

パラメータの再割り当てをチェックする Checkstyle-Check があるため、パラメータは最終的なものではありません。もちろん、誰もパラメーター変数を再割り当てしたくないでしょう。

于 2008-11-25T07:10:13.600 に答える
0

Google コレクション API の使用により増加している匿名クラスで使用されている場合は、Eclipse に任せます。

于 2008-11-25T05:54:35.390 に答える
0

なぜあなたはしたいですか?メソッドを作成したので、それを変更する人はいつでも qwerty から final キーワードを削除して再割り当てできます。メソッドの署名については、同じ理由ですが、クラスのサブクラスに何をするかはわかりません...最終パラメーターを継承する可能性があり、メソッドをオーバーライドしたとしても、x を非ファイナライズできません。試してみて、それが機能するかどうかを確認してください。

したがって、唯一の本当の利点は、パラメーターを不変にして子に引き継ぐ場合です。そうしないと、特に正当な理由もなく、コードが乱雑になります。誰もあなたのルールに従うことを強制しない場合は、最後の修飾子を指定する代わりに、そのパラメーターまたは変数を変更してはならない理由として、適切なコメントを残す方がよいでしょう。

編集

コメントに応えて、パフォーマンスの問題が発生している場合は、ローカル変数とパラメーターを final にすることで、コンパイラーがコードをより適切に最適化できるようになることを追加します。ただし、コードの不変性の観点から、私は元の声明を支持します。

于 2008-11-25T04:23:39.287 に答える