public class MySingleton{
private static final MySingleton INSTANCE = new MySingleton();
private MySingleton(){}
public static getInstance(){
return INSTANCE;
}
}
これはシングルトンを実装する正しい方法ですか。はいの場合、最終的なキーワードの必要性は何ですか?
Finalは、作成後にインスタンスが変更できないようにします。コンストラクターのみを含み、セッターを含まない場合、それは大したことではありません。誰もあなたのインスタンスを変更することはできず、あなたはそれを変更していません。
クラスが後で変更された場合に備えて、そのままにしておくのは悪い考えではありません。不変性にはいくつかの利点があります(シリアル化が容易、誰かがオブジェクトを後ろで変更することに対する保険など)。
不変性を元に戻すのは、取り出すよりも難しいです。後でだれもそれを台無しにできないように、防御的にコードを書いてください。
一般的に好ましいアプローチは、列挙型を使用することです
public enum MySingleton {
INSTANCE;
}
あなたの例では、最後のキーワードは意図を示しており、再割り当て(=バグ)を防ぎますが、厳密には必要ありません。
特に、変数は静的であるため、マルチスレッド環境で安全に公開するために最終的なものである必要はありません。
Java でシングルトン パターンを実装する唯一の正しい方法はありませんが、遅延読み込みが必要なく、単体テストの結果を受け入れることができる場合は、public static final インスタンス変数を使用することをお勧めします。
単体テストが問題であり、シングルトンが必要な場合は、依存性注入の使用を検討してください。これにより、シングルトン ライフサイクルを使用して通常のインスタンスを構成できます。
final 修飾子を使用すると、Java コンパイラとランタイムが適切な最適化とスレッド セーフの決定を行うことができます。私は常に、このスタイルのシングルトン宣言で final を使用します。シングルトン インスタンスをミュータブルにするのは、設計上の選択として不適切であると言えます。クライアント コードは、プロセスの存続期間中、同じ値を参照することに依存できなくなるためです。
構成可能なファクトリ クラスを使用して、単体テストの問題に対処することができます。
private static final MySingleton INSTANCE = MySingletonFactory.create();
...最終的な利点を失うことなく。
本当に必要ではありません。ただし、finalを使用すると、真のシングルトンを強制するシングルトンクラス自体でリセットすることはできません。ただし、シングルトンは不適切な方法であるため、setInstance()メソッドを追加することで単体テストに使用できるようにすることができます。気になる人は、単体テストがリフレクションを介してsetInstanceを呼び出すように、setInstanceprivateを定義できます。