it-swarm.com.de

Java: getInstance vs Static

Was ist der Zweck von getInstance() in Java? 

Während meiner Recherchen lese ich immer wieder, dass getInstance() dazu beiträgt, ein Singleton-Entwurfsmuster zu erzielen (was nach meinem Verständnis nur eine Instanz im gesamten Programm bedeutet). Aber kann ich nicht einfach statisch verwenden? Ist das nicht der Punkt von statisch?

Wenn ich nur statische Methoden und Felder hätte, wie würde sich das von der Verwendung von getInstance() unterscheiden? Gibt es einen "Spielraum" von Statik? Zum Beispiel eine Instanz pro Methode oder Klasse?

Und wenn sie sich unterscheiden, in welchen Fällen würde ich getInstance() die Verwendung von static wählen?

Ich entschuldige mich, wenn die Frage unklar ist. Ich bin sicher, dass mir bei diesem Thema etwas fehlt, ich kann einfach nicht herausfinden, was.

Vielen Dank für alle Ratschläge.

25
FreakyDan

Static gibt Ihnen keinen Singleton. Da es nicht möglich ist, aus einer Top-Level-Klasse ein Singleton in Java zu machen, gibt es getInstance-Methoden, die eine Logik implementieren, um sicherzustellen, dass nur eine Instanz einer Klasse vorhanden ist.

public class Singleton {

   private static Singleton singleton;

   private Singleton(){ }

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

}

Sehen Sie sich diese Antwort an: Statische Klassen in Java

Mit dem obigen Code kann nur eine Instanz erstellt werden. Dies ist sauber. Ab Java 1.6 ist es jedoch besser, Singletons als solche zu erstellen, da IMHO etwas eleganter ist:

public enum MyEnumSingleton {
    INSTANCE;

    // other useful methods here
} 

Quelle: http://www.vogella.com/tutorials/DesignPatternSingleton/article.html

15
Zac Lozano

Singleton

Mit einem Singleton können Sie einen einzelnen Verweis auf ein Java-Objekt verwenden. Zum Beispiel ist hier ein Singleton, der eine Zahl enthält;

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;
    }
}

Jetzt setzen wir den Wert dieser Zahl in der A-Klasse:

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

Dann können Sie von einer anderen Klasse auf diesen Wert zugreifen:

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

In dieser Klasse hat die Variable number den Wert 42. Dies ist der Vorteil eines Singleton-Objekts gegenüber einem einfachen Objekt:

Auf alle im Singleton gespeicherten Werte kann über .__ zugegriffen werden. "überall".


Statische Klasse

Der Zweck ist anders, hier ist der Vorteil, ein Objekt zu verwenden, ohne es erstellen zu müssen.

Zum Beispiel:

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

Jetzt können Sie die sayHello () - Methode aus beliebigen Klassen verwenden, indem Sie Folgendes aufrufen:

MyStaticClass.sayHello(); 
8
G.T.

Die genaue Methode zum Implementieren eines Singleton, zum Beispiel unter Verwendung einer Factory-Methode mit dem Namen getInstance(), ist für die Frage nicht relevant, nämlich "statische Methoden vs. Singleton mit Instanzmethoden".

Klassen sind selbst effektiv Singletons, daher sind sie unter diesem Aspekt ähnlich.

Der Hauptunterschied besteht darin, dass statische Methoden nicht Teil der Klassenhierarchie sind - sie werden nicht vererbt. Dies bedeutet, dass Sie mit der Option statische Methode die Verwendung dieser Klasse für immer blockieren und nicht auf andere Weise, z von einer Schnittstelle oder einer Superklasse.

Instanzen haben jedoch dieses Problem nicht, sodass Sie beispielsweise Folgendes codieren können:

class MySingleton implements SomeInterface {
    ...
}

SomeInterface instance = MySingleton.getInstance();
3
Bohemian

Ich bevorzuge auch static, aber manchmal ist getInstance() hilfreich, um einige Funktionen zu haben, die sich auf das Objekt beziehen, in dem Sie Variablen ändern können. Wenn Sie lediglich einige nützliche Funktionen erstellen, die keine Instanz eines Objekts benötigen, verwenden Sie static.

Wenn Sie die Bibliotheken einer Person verwenden, wissen Sie nie, ob ein Funktionskörper eine Klasseninstanz benötigt. Aus diesem Grund verwenden viele Bibliotheksklassen getInstance().

1
Victor2748

Anstatt nach Null zu suchen, gefällt mir das etwas besser.

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;
    }
}

Angerufen mit ...

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();
   }
}

Vollständiger Code von: http://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

0
Jason

Ein übersehener Grund für die Verwendung eines Singleton anstelle von statischen Klassenmitgliedsvariablen besteht darin, dass die statischen Membervariablen MÖGEN Platz und Speicherbereinigungszeit verwenden können, selbst wenn die Klasse niemals instanziiert wird. Bedenken Sie, wie viele Klassen in rt.jar verfügbar sind und welchen Bruchteil Sie wahrscheinlich in einer bestimmten Anwendung verwenden. Beachten Sie auch, dass mit getInstance sichergestellt wird, dass Ihr "Konstruktor" ausgeführt wurde, bevor auf eine der Member-Variablen zugegriffen wird. Ich sehe getInstance fast immer als synchronisiert, aber ich denke, dass dies eine schlechte Idee ist. Wenn irgendjemand jemals eine synchronisierte Blockierungsmethode aufruft, kann dies zu Singleton.getInstance () führen. Unsynchronized () könnte unnötig aufgehalten werden.

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() );
}
0
William Deans