web-dev-qa-db-ja.com

Java:getInstanceとStatic

JavaのgetInstance()の目的は何ですか?

私の研究中、getInstance()はシングルトン設計パターンの実現に役立つことを読み続けています(これは、プログラム全体で1つのインスタンスのみを意味します)。しかし、静的なものだけを使用することはできませんか?それが静的なポイントではないでしょうか?

静的なメソッドとフィールドのみを使用する場合、getInstance()を使用することとどのように違いますか?静的な「スコープ」はありますか?たとえば、メソッドまたはクラスごとに1つのインスタンスですか?

そして、それらが異なる場合、どのような場合に静的を使用するよりもgetInstance()を選択しますか?

質問が不明確な場合は謝罪します。主題について何かが欠けていると確信しています。何がわかるのかわかりません。

ありとあらゆるアドバイスをありがとう。

28
FreakyDan

Staticはシングルトンを与えません。 Javaでトップレベルクラスをシングルトンにする方法はないため、クラスのインスタンスが1つだけであることを確認するためのロジックを実装するgetInstanceメソッドがあります。

public class Singleton {

   private static Singleton singleton;

   private Singleton(){ }

   public static synchronized Singleton getInstance( ) {
      if (singleton == null)
          singleton=new Singleton();
      return singleton;
   }

}

このトップアンサーをご覧ください: Static Classes In Java

上記のコードでは、インスタンスを1つしか作成できず、クリーンです。ただし、Java 1.6の時点では、シングルトンのインスタンスを作成する方が、よりエレガントなIMHOです。

public enum MyEnumSingleton {
    INSTANCE;

    // other useful methods here
} 

ソース: http://www.vogella.com/tutorials/DesignPatternSingleton/article.html

15
Zac Lozano

シングルトン

シングルトンを使用すると、Java Object。への単一の参照を使用できます。

public class MySingleton {

    private int myNumber;
    private static MySingleton instance;

    public static MySingleton getInstance() {
        if (instance == null) {
             instance = new MySingleton();
        }
        return instance;
    }

    private MySingleton() {}

    public void setMyNumber(int myNumber) {
        this.myNumber = myNumber;
    }

    public int getMyNumber() {
       return myNumber;
    }
}

次に、Aクラスでこの数値の値を設定します。

public class A {
    /*...*/
    MySingleton mySingleton = MySingleton.getInstance();
    mySingleton.setMyNumber(42);
    /*...*/
}

次に、別のクラスからこの値にアクセスできます。

public class B {
    /*...*/
    MySingleton mySingleton = MySingleton.getInstance();
    int number = mySingleton.getMyNumber();
    /*...*/
}

このクラスでは、number変数の値は42になります。これは、単純なオブジェクトに対するシングルトンの利点です。

シングルトンに保存されているすべての値には、「どこからでも」アクセスできます。


静的クラス

目的は異なります。ここでの利点は、オブジェクトを作成せずに使用することです。

例えば:

public static class MyStaticClass {
    public static void sayHello() {
        System.out.println("Hello");
    }
}

これで、次の呼び出しにより、任意のクラスからsayHello()メソッドを使用できます。

MyStaticClass.sayHello(); 
9
G.T.

たとえばgetInstance()と呼ばれるファクトリメソッドを使用してシングルトンを実装する正確な方法は、「インスタンスメソッドを使用した静的メソッドとシングルトン」という質問には関係ありません。

クラスはそれ自体が事実上シングルトンなので、その観点からはクラスは似ています。

主な違いは、静的メソッドはクラス階層の一部ではないことです-継承されないため、静的メソッドオプションはその正確なクラスの使用を永久にロックし、実装など他の方法で参照することはできませんインターフェースまたはスーパークラスの.

ただし、インスタンスにはこの問題がないため、たとえば次のようにコーディングできます。

class MySingleton implements SomeInterface {
    ...
}

SomeInterface instance = MySingleton.getInstance();
3
Bohemian

私はstaticも使用することを好みますが、変数を変更できるオブジェクトに関連するいくつかの関数があると、getInstance()が役立つ場合があります。オブジェクトのインスタンスを必要としないutil関数を単に作成する場合は、staticを使用します。

誰かのライブラリを使用している場合、関数本体にクラスインスタンスが必要かどうかはわかりません。それが、多くのライブラリクラスがgetInstance()を使用している理由です。

1
Victor2748

静的クラスメンバー変数の代わりにシングルトンを使用する見落とされがちな理由の1つは、クラスがインスタンス化されない場合でも、静的メンバー変数がスペースとガベージコレクター時間を使用する場合があることです。 rt.jarで使用できるクラスの数と、特定のアプリケーションで使用するクラスのごく一部を検討してください。また、getInstanceを使用すると、メンバー変数にアクセスする前に「コンストラクター」が実行されることを確認してください。私はほぼ普遍的にgetInstanceが同期されていると見ていますが、これは悪い考えだと感じています。誰かが同期化されたブロッキングメソッドを追加すると、Singleton.getInstance()。unsynchronized()への呼び出しが不必要に保持される可能性があります。

private static Singleton instance = null;
private Singleton() {}
public final static Singleton getInstance() {
    return (instance != null) ? instance : makeInstance();
}
private final static synchronized Singleton makeInstance() {
    return ( instance != null ) ? instance : ( instance = new Singleton() );
}
1
William Deans

Nullをチェックする代わりに、私はこれをもう少し気に入っています。

public class SingleObject {

    //create an object of SingleObject
    private static SingleObject instance = new SingleObject();

    //make the constructor private so that this class cannot be
    //instantiated
    private SingleObject(){}

    //Get the only object available
    public static SingleObject getInstance(){
        return instance;
    }
}

と呼ばれる...

public class SingletonPatternDemo {
   public static void main(String[] args) {

      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //SingleObject object = new SingleObject();

      //Get the only object available
      SingleObject object = SingleObject.getInstance();
   }
}

完全なコード: http://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

0
Jason