4

@Singleton サーブレットの存続期間中に変更したくない変数の初期化に関して、サーブレットには 2 つのオプションがあります。

Field a;

フィールド a は、サーブレットによってのみ内部的に使用されます。アクセサ メソッドはありません。簡単にするために、フィールド a は文字列のように不変です。

オプション 1 - フィールドが次のようになるように、ServletContext の依存性注入から取得した情報を利用して、コンストラクター内のフィールドを初期化します。

private final Field a;

オプション 2 - フィールドが次のようになるように、ServletConfig (および ServletContext) から取得した情報を利用して、オーバーライドされた init(ServletConfig cfg) メソッドで変数を設定します。

private Field a;

明らかに、フィールドを final にしたいのですが、このフィールドは非公開であり、アクセサー メソッドが関連付けられていないので、それでも final にする必要がありますか?

要約すると、フィールドをコンストラクターで初期化して final にするか、init メソッドで初期化してアクセサーなしで非 final のままにする必要がありますか?

ありがとうございました。

4

3 に答える 3

2

もちろん、フィールドをファイナルにしたいのですが、フィールドはプライベートであり、アクセサーメソッドがアタッチされていないので、それでもファイナルにしようとすべきでしょうか?

はい。それはあなたの意図をより明確にします。それが最終的でない場合、誰も後でそれを変更するメソッドを追加せず、それでも変更されないことを効果的に想定しているコードを残すことにどれだけ賭けるつもりですか?

于 2012-05-17T15:56:54.923 に答える
2

宣言することの利点はfinal、コードのどこかで誤って変更しないことです。

于 2012-05-17T15:57:14.477 に答える
1

意図を明確に文書化し、コードを理解して維持しやすくすることに加えて、final修飾子はマルチスレッドアプリケーションでいくつかの重要な保証を提供します。

サーブレット仕様で保証されているかどうかはわかりませんが、実際には、サーブレットエンジンは、新しいサーブレットインスタンスの内部状態がそれを使用するすべてのスレッドに表示されるようにするメモリバリアを使用する必要があるようです。サーブレットリクエストを処理します。これは「安全な公開」と呼ばれます。

ただし、一般的にはそうではありません。「オプション2」と表現するのは「効果的な不変性」です。オブジェクトには、ではないフィールドがありますが、final構築または初期化ステップの後にそのフィールドを変更することはできません。ただし、他のスレッドがメモリバリアを通過せずにこのオブジェクトにアクセスする場合、このフィールドがオブジェクトのコンストラクターで設定されていても、初期化スレッドによってそのフィールドに割り当てられた値が表示されない可能性があります。

ただし、オブジェクトの構築中にフィールドに割り当てられた値finalは、オブジェクト自体が「安全に公開」されていない場合でも、他のすべてのスレッドに表示されることが保証されています。

于 2012-05-17T16:17:54.190 に答える