回答:
素晴らしい本によると、「効果的なJavaの」:
項目4:プライベートコンストラクターでインスタンス化不能を強制する
-クラスを抽象化してインスタンス化不可能性を強制しようとしても機能しません。
-デフォルトのコンストラクターは、クラスに明示的なコンストラクターが含まれていない場合にのみ生成されるため、プライベートコンストラクターを含めることでクラスをインスタンス化できなくすることができます。
// Noninstantiable utility class
public class UtilityClass
{
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
}
明示的なコンストラクターはプライベートであるため、クラスの外からはアクセスできません。AssertionErrorは厳密には必須ではありませんが、コンストラクターがクラス内から誤って呼び出された場合に備えて保証されます。これにより、どのような状況でもクラスがインスタンス化されないことが保証されます。このイディオムは、コンストラクターが明示的に提供されているため、呼び出せないため、少し直感に反しています。したがって、上記のようにコメントを含めるのが賢明です。
副作用として、このイディオムはクラスがサブクラス化されることも防ぎます。すべてのコンストラクターは、明示的または暗黙的にスーパークラスコンストラクターを呼び出す必要があり、サブクラスには、呼び出すアクセス可能なスーパークラスコンストラクターがありません。
AssertionError
のような他の選択肢を超えるIllegalStateException
、UnsupportedOperationException
など、?
あなたはjava.lang.Mathに似たユーティリティクラスを持っているように聞こえます。
そこでのアプローチは、プライベートコンストラクターと静的メソッドを備えた最終クラスです。
しかし、これはテスト容易化のために、私はこの記事を読んでお勧めしないものの用心
静的メソッドは、テスト容易に死です
上流を泳ぐためだけに、静的メンバーとクラスはOOに参加しないため、悪です。いいえ、悪ではありませんが、真剣に、アクセスにはシングルトンパターンの通常クラスをお勧めします。このようにして、将来的に動作をオーバーライドする必要がある場合でも、大きな改造ではありません。OOはあなたの友達です:-)
私の$ .02
「プライベートコンストラクタ」の引数についてコメントします。さあ、開発者はそれほど愚かではありません。しかし、彼らは怠惰です。オブジェクトを作成してから静的メソッドを呼び出しますか?起こりません。
クラスが誤用されないように、時間をかけすぎないようにしてください。同僚を信頼してください。クラスをどのように保護しても、クラスを誤用する方法が常にあります。悪用できないのは、まったく役に立たないことだけです。
クラスをとして宣言しても意味がありませんstatic
。メソッドstatic
を宣言して、JavaのMathクラスのように、通常どおりクラス名から呼び出すだけです。
また、コンストラクターをプライベートにする必要はありませんが、プライベートにすることをお勧めします。コンストラクターをプライベートにマークすると、他のユーザーがクラスのインスタンスを作成して、それらのインスタンスから静的メソッドを呼び出すことができなくなります。(これらの呼び出しはJavaでもまったく同じように機能しますが、誤解を招きやすく、コードの読みやすさに悪影響を及ぼします。)
lombokから@UtilityClassアノテーションを使用できますhttps://projectlombok.org/features/experimental/UtilityClass