2009-08-25 28 views
15

最近、私は質問に直面しました:Javaクラスのインスタンス化を避けるにはどうしたらいいですか?Javaクラスのインスタンス化を避ける

しかし、私が言って答え:あなたは、クラスをインスタンス化したくない場合は

  1. 、「抽象的」修飾子を使用します。例:javax.servlet.HttpServletは、インスタンス化を避けるため抽象クラスとして宣言されています(抽象メソッドはありません)。

  2. 引数なしのプライベートコンストラクタを宣言します。

私の質問は です)他の方法はありますか? b)なぜ誰かがクラスをインスタンス化したくないのですか? - SOで検索した後、私はthisからUtilクラスをインスタンス化しないことを知っておく必要があります。 OOPでクラスをインスタンス化したくない他の場所?

答えて

24

4つの理由は、心に春:

  1. は、サブクラスではなく、親インスタンス化することを可能にするには、
  2. インスタンシエーションを許可せず、代わりにインスタンスを返し、必要に応じて作成するファクトリメソッドを提供します。
  3. Java 5以降では、すべてのインスタンスが事前定義されているため(例:カードデッキ内のスーツ)、代わりに型保証された列挙型が推奨されます。
  4. クラスは本当にクラスではありません。静的な定数やメソッドの単なる保持者です。

(2)の例として、標準オブジェクトを作成することができます。たとえば、RGBの色の組み合わせ。あなたは、あなたがこれを行うように、任意のRGBコンボの複数のインスタンスを作成する必要はありません:

public class MyColor { 
    private final int red, green, blue; 

    private MyColor(int red, int green, int blue) { 
    this.red = red; 
    this.green = green; 
    this.blue = blue; 
    } 

    public static MyColor getInstance(int red, int green, int blue) { 
    // if combo already exists, return it, otherwise create new instance 
    } 
} 

注:別のコンストラクタを明示的に定義されているためなし引数なしのコンストラクタが必要です。

2

私は、クラスをインスタンス化したくないというもっとも一般的な理由は、静的なクラスを扱うとき、したがってその静的メソッドを扱うときです。誰かがそのクラスをインスタンス化しようとしないようにします。同様に、Factoryクラスを扱っている場合や、多くの場合、多くのシングルトンクラスは、通常の方法でインスタンス化されないようにそのコンストラクタを非表示にします。

3

既存のインスタンスすべてを完全に制御できるように、オブジェクトをインスタンス化することを避けたい場合もあります。 1つの例はsingleton patternです。

1

クラスをインスタンス化できないようにする別の方法は、それをプライベート内部クラスとして宣言し、それを周囲のクラスでインスタンス化する方法を提供しないことです。しかし、これは(IMO)かなり無意味です。

クラスをインスタンス化することが意味をなさない場合は、インスタンス化できないようにします。クラスが本当に(静的な)ヘルパーメソッドのコレクションである場合、またはクラスが「不完全」である場合は、これを一般的に行います。不完全性は構文的に明らかである(すなわち、抽象的な方法)が、他の種類の不完全さがあるかもしれない。たとえば、すべてのメソッドの既定の既定の実装を提供し、それらのうちの1つまたは複数を上書きして、クラスが有用なものを実行するようにすることができます。

クラスをインスタンス化できない(または少なくともインスタンス化できない)別の理由は、アプリケーションでインスタンス化を制御する必要がある場合です。たとえば、java.util.regex.Patternクラスを直接インスタンス化することはできません。そのため、JREは事前コンパイル済みの正規表現のキャッシュを維持できます。

8

本当にあなたの質問への答えが、ちょうどない注:あなたのユーティリティクラスのインスタンス化を防ぐために、民間の引数なしのコンストラクタを作るとき

、あなたはコンストラクタが例外(例えば、UnsupportedOperationExceptionが)投げる必要があります。これは、リフレクションを通じて実際にプライベートメンバー(コンストラクタを含む)にアクセスできるからです。その場合は、コンストラクタをに定義することは、直感的ではないため、のクラスのインスタンス化を防止するため、コメントを付ける必要があります。

ユーティリティクラスを抽象的にすることは、クラスを拡張しようとしているように見えるため、クラスを拡張してインスタンス化することができます。

関連する問題