OOP Verständnisfrage zu Singelton Pattern

Iago

Mitglied
Hallo,
ich habe eine Frage bezülich des Feldes instanz zu folgendem Code:
Java:
public class Singelton
{
   private static Singelton instanz = null;

   private Singelton() {}

   public static Singelton getInstanz()
   {
      if (instanz == null)
         instanz = new Singelton();

      return instanz;
   }
 }

//in irgendeiner anderen Klasse
Singelton obj1 = Singelton.getInstanz();
Singelton obj2 = Singelton.getInstanz();

Wie kann man das verstehen, dass das Feld instanz von der "Art" Singelton ist. private besagt, dass das Feld nicht öffentlich ist, static, dass es nicht an die Instanziierung eines Objektes gebunden ist, aber wozu dann noch Singelton vor dem Feldnamen?

Danke, Iago
 

Volvagia

Top Contributor
Muss man doch bei allen Variablen machen. ???:L

Sehr wichtig:

Java:
if (instanz == null)
    instanz = new Singelton();

So ein Code muss immer synchronisiert werden. Damit du dir das aber erspaarst kannst du einen static constructor anlegen und in dem die Variable setzen.
 
M

maki

Gast
static Konstruktor? Nee.. ;)

Bei diesem Beispiel kann er auch einfach komplett auf das Lazyinit und dadurch auch auf synchronisation verzichten:
Java:
public class Singelton
{
   private static Singelton instanz = new Singleton();
 
   private Singelton() {}
 
   public static Singelton getInstanz()
   {
      return instanz;
   }
 }
.. und eigentlich auf die Methode auch:
Java:
public class Singelton
{
   public final static Singelton INSTANCE = new Singleton();
 
   private Singelton() {}
 
 }

Ansonsten sehe ich das wie Landei, das GoF Singleton hat Konsequenzen.
 

Wildcard

Top Contributor
Davon abgesehen das ich Landei und maki natürlich zustimme, das GoF Singleton ist ein Anti-Pattern, ist mir unbegreiflich warum jeder immer meint besonders clever sein müssen mit 'Lazy-Init'.
Java:
if (instanz == null)
    instanz = new Singelton();
Es gibt fast keinen Fall wo dieser Code Vorteile bringt. In allen anderen Fällen führt es zu Problemen mit Threads, führt unnötige Codezeilen ein, INSTANCE kann nicht mehr final sein und dann ist auch noch etwas langsamer. :autsch:
Leider bekomme ich das auch meinen Kollegen nicht eingeimpft.
 

Lumaraf

Bekanntes Mitglied
static Konstruktor? Nee.. ;)

Bei diesem Beispiel kann er auch einfach komplett auf das Lazyinit und dadurch auch auf synchronisation verzichten:
Java:
public class Singelton
{
   private static Singelton instanz = new Singleton();
 
   private Singelton() {}
 
   public static Singelton getInstanz()
   {
      return instanz;
   }
 }
.. und eigentlich auf die Methode auch:
Java:
public class Singelton
{
   public final static Singelton INSTANCE = new Singleton();
 
   private Singelton() {}
 
 }

Auf aktuellen JVMs wird die Initialisierung in dem Fall sogar lazy ausgeführt. Klassen werden erst initialisiert wenn das erste mal eine Methode davon aufgerufen wird. Um die synchronization braucht man sich dann auch keine Sorgen machen, die JVM kümmert sich da schon drum.

Java:
public class SingletonTest
{
	public static void main(final String[] args)
	{
		SingletonTest.test(false);
		SingletonTest.test(true);
	}

	public static void test(final boolean b)
	{
		System.out.println("before");
		if (b)
			System.out.println(Singleton.instance);
		System.out.println("after");
		System.out.println();
	}
}

class Singleton
{
	public static Singleton instance = new Singleton();

	private Singleton()
	{
		System.out.println("instance created");
	}
}

Die Instanz von Singleton wird erst beim Aufruf von test(true) erzeugt und nicht vorher.
 
Zuletzt bearbeitet:

Landei

Top Contributor
Wenn man wirklich ein lazy-loading, thread-safe Singleton haben will, gibt es - so weit ich weiß - nur zwei einfache und wirklich "saubere" Lösungen:

1) Eine statische innere Klasse hält die Referenz:
Java:
public final class Foo {

    private static class FooLoader {
        private static final Foo INSTANCE = new Foo();
    }

    private Foo() {}

    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }
}

2) Seit Java 1.5 der bevorzugte Stil: Man benutzt ein [c]enum[/c].
Java:
public enum Foo {
   INSTANCE;
}

Achtung, zusätzliche Vorkehrungen sind notwendig, wenn die Singletons serialisiert werden müssen!

Man sieht oft wilde Implementierungen, die mit synchronized und dem double-checked locking pattern herumhantieren, aber sie sind nicht nur komplizierter, sondern schlicht unbrauchbar: The "Double-Checked Locking is Broken" Declaration
 

Wildcard

Top Contributor
Wenn man wirklich ein lazy-loading, thread-safe Singleton haben will, gibt es - so weit ich weiß - nur zwei einfache und wirklich "saubere" Lösungen:
Was dabei oft missverstanden wird, die einfache Variante das Feld direkt zu initialisieren ist auch fast immer Lazy Loading, weil die Variable erst dann initialisiert wird wenn die Klasse geladen wird, also wenn sie wirklich gebraucht wird.
Der einzige Fall in dem die Instanz zu früh erstellt werden würde, ist wenn die Klasse, oder statische Methoden der Klasse verwendet werden ohne das auch gleich nach der Singleton Instanz gefragt wird. Und dafür gibt es nun wirklich fast keinen validen Use-Case.
 
M

maki

Gast
Gibt es irgendwo ein Beispiel, wie man mit Dependency Injections Singeltons ersetzen kann?
Wirklich jedes DI Framework beschreibt genau das in der Doku.

Ist gar nicht so komplex wie man meint, Singletons stellen externe Abhängkeiten dar, diese werden in DI entweder per Setter, Konstruktor oder Annotationen "injeziert", also als Parameter übergeben.
 

ARadauer

Top Contributor
Die Frage hatte gar nix mit Singletons zu tun. Der Threadsteller fragt einfach nur warum er den Typ vor eine Variable schreiben muss. Ja weil eine Variable halt einen Typ braucht! Man muss ja issen ob instanz eine Zahl, ein Kunde, ein Huhn oder dein Singelton Objekt ist.

Gibt es irgendwo ein Beispiel, wie man mit Dependency Injections Singeltons ersetzen kann?
Wie jetzt konkret ein Code Beispiel?

Statt
Java:
public class SingletonUser {

   public void doSomethingWithSingleton(){
      Singleton.getInstanz().doSometing(); 
   }
}

sich zb per Konstruktor Injection das Teil setzen lassen

Java:
public class SingletonUser {
   
   private Singleton singleton;
   
   
   public SingletonUser(Singleton singleton) {
      super();
      this.singleton = singleton;
   }


   public void doSomethingWithSingleton(){
      singleton.doSometing(); 
   }
}
Wobei jetzt Singleton eine ganz normale POJO wäre und keine static instanz und private Konstrutor braucht. Und ein Bissal Konfig je nach DI Framework noch fehlt
 

Landei

Top Contributor
In Guice kann man entweder die zu injizierende Klasse mit [c]@Singleton[/c] annotieren, oder alternativ als Eigenschaft beim Binden angeben. Für die Klasse, die das Ding injiziert bekommt, sieht das Singleton wie jeder andere injizierte Wert aus.
 
N

nillehammer

Gast
Hallo,
das hier diskutierte Pattern ist veraltet. Die verschiedenen Nachteile sind ja bereits ausführlich diskutiert worden. Seit Java 5 gibt es ein viel robusteres Pattern mit Enums.

Java:
public enum MySingleton {
  INSTANCE;
  ... felder ...
  ... methoden ...
}
Das ist schon alles. Die Vorteile sind: Viel weniger Code, es gibt keine Probleme mit Threads, es ist unter keinen Umständen möglich, dass man aus versehen doch mehrere Instanzen erzeugt, enums sind sogar out of the box serializable.

Zugriff erfolgt über MySingleton.INSTANCE.

Gruß nillehammer
 
S

SlaterB

Gast
Man sieht oft wilde Implementierungen, die mit synchronized und dem double-checked locking pattern herumhantieren, aber sie sind nicht nur komplizierter, sondern schlicht unbrauchbar: The "Double-Checked Locking is Broken" Declaration

wenn es nicht gerade um eine komplette Klasse geht sondern um einfache Instanzattribute dann sind die meisten bis alle hier genannten Varianten ja wenig hilfreich,
zum DoubleCheckedLocking mag wer will vielleicht jemand in meinen Thread schauen:
http://www.java-forum.org/allgemeine-java-themen/122208-double-checked-locking.html
 

freez

Top Contributor
Wirklich jedes DI Framework beschreibt genau das in der Doku.

Ich habe etwas recherchiert und festgestellt, dass JEE6 in der Regel benötigt wird. Was ist nun, wenn ich einfach nur ne Desktop Applikation z.B. in Swing entwickle. Nehme ich da auch ein DI Framework als Ersatz für:
Java:
public static Singelton getInstanz(){
      if (instanz == null)
         instanz = new Singelton();
      return instanz;
   }

Der Tipp von nillehammer mit ENUM gefällt mir ganz gut.
 
M

maki

Gast
Ich habe etwas recherchiert und festgestellt, dass JEE6 in der Regel benötigt wird.
Weder Spring noch Guice brauchen JEE 6, hast wohl nicht so gut recherchiert ;)
JEE6 bietet (C)DI, hast du wohl verwechselt.


Was ist nun, wenn ich einfach nur ne Desktop Applikation z.B. in Swing entwickle. Nehme ich da auch ein DI Framework als Ersatz für:
Natürlich.

Java:
public static Singelton getInstanz(){
      if (instanz == null)
         instanz = new Singelton();
      return instanz;
   }
Frage an dich freeze:
Wozu das Lazy Init?

Bei kleinen Systemen (ohne JEE oder Spring) würde ich auch Guice empfehlen.
Kann Guice auch für große Systeme empfehlen :)
 

Noctarius

Top Contributor
Kann Guice auch für große Systeme empfehlen :)

Ich auch, aber in dem Bereich in dem ich arbeite (Web-Backends ^^), sind große Systeme meistens schon auf JEE oder Spring Basis. Dort wird meistens kaum einer auf Guice aufbauen.
Das es auch für größere Dinge wunderbar ist sehe ich an meinem Chatserver, der um Guice herum ein großes Framework aufgebaut hat :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Java Iterator Verständnisfrage Java Basics - Anfänger-Themen 6
A Verständnisfrage Java Basics - Anfänger-Themen 12
M Verständnisfrage: Warum wird die Datei ohne Inhalt übertragen Java Basics - Anfänger-Themen 3
P Verständnisfrage: PageFactory.initElements Java Basics - Anfänger-Themen 2
R do while Schleife Verständnisfrage Java Basics - Anfänger-Themen 2
G while.next() Verständnisfrage Java Basics - Anfänger-Themen 16
Vivien Kurze Verständnisfrage zu Java Point aus java.awt.* Java Basics - Anfänger-Themen 5
C Erste Schritte Anfänger Verständnisfrage zum Compiler Java Basics - Anfänger-Themen 31
T Verständnisfrage Objekt Getter Setter Java Basics - Anfänger-Themen 102
K Verständnisfrage Server/Client BufferedReader, PrintWriter Java Basics - Anfänger-Themen 2
Der Grütz Verständnisfrage zu Übung aus Java Kurs - Schaltjahr bestimmen Java Basics - Anfänger-Themen 2
J Verständnisfrage zu throws neben Funktionen Java Basics - Anfänger-Themen 2
TimoN11 Verständnisfrage bei Aufgabe Java Basics - Anfänger-Themen 2
P Verständnisfrage zum Mapping Java Basics - Anfänger-Themen 3
M Java Version Verständnisfrage Java Basics - Anfänger-Themen 16
M Verständnisfrage zu eine Online Aufgabe Java Basics - Anfänger-Themen 7
T Verständnisfrage zur Konsolenausgabe Java Basics - Anfänger-Themen 2
M Verständnisfrage zu Generics Java Basics - Anfänger-Themen 7
D Verständnisfrage zur Modellierung einer HDD Java Basics - Anfänger-Themen 17
W Methoden Verständnisfrage Vererbung von Methoden Java Basics - Anfänger-Themen 14
S Verständnisfrage lokale Ordnerpfade Java Basics - Anfänger-Themen 1
T Verständnisfrage zu Interfaces Java Basics - Anfänger-Themen 7
J Java Starthilfe Verständnisfrage Aufgabe Java Basics - Anfänger-Themen 2
O Anfänger, Verständnisfrage Java Basics - Anfänger-Themen 3
C Verständnisfrage zu Modulo Java Basics - Anfänger-Themen 6
C Verständnisfrage bezüglich der Do-While Schleife Java Basics - Anfänger-Themen 9
L Verständnisfrage - Speicherabbild Java Basics - Anfänger-Themen 4
melly_ Verständnisfrage zu args Java Basics - Anfänger-Themen 3
A Variablen Verständnisfrage bzgl. Variablen/Referenzen Java Basics - Anfänger-Themen 3
K Verständnisfrage eines Abschnitts Java Basics - Anfänger-Themen 6
K Rekursion Verständnisfrage Java Basics - Anfänger-Themen 19
S Modell View Controller Verständnisfrage Java Basics - Anfänger-Themen 24
J Superklassen Konstruktor Verständnisfrage Java Basics - Anfänger-Themen 1
JavaTalksToMe Erste Schritte Println-Frage (Verständnisfrage) Java Basics - Anfänger-Themen 1
R Verständnisfrage zu Objekten u. Übergabeparameter Java Basics - Anfänger-Themen 8
G Collections Verständnisfrage zur For-Each-Schleife Java Basics - Anfänger-Themen 7
b1ck Interface Verständnisfrage zum GUI mit "swing" Java Basics - Anfänger-Themen 1
kilopack15 Verständnisfrage zur Verwendung von notify() bei Threads Java Basics - Anfänger-Themen 2
G Verständnisfrage zu for-each Java Basics - Anfänger-Themen 4
DontFeedTheTroll Erste Schritte Verständnisfrage zu If-Anweisung Java Basics - Anfänger-Themen 7
K Rekursion-Verständnisfrage Java Basics - Anfänger-Themen 4
J Java Server Pages - Verständnisfrage Java Basics - Anfänger-Themen 2
Z Verständnisfrage Anfängerprogramm Java Basics - Anfänger-Themen 0
T Verständnisfrage Zuweisungs-/arithmet. Operatoren Java Basics - Anfänger-Themen 2
G Methoden Verständnisfrage zur Methoden Java Basics - Anfänger-Themen 7
LionAge Kapselung, Verständnisfrage zur Objekterzeugung Java Basics - Anfänger-Themen 4
Z Verständnisfrage zum Multithreading Java Basics - Anfänger-Themen 3
R OOP / Verständnisfrage zum Konstuktor (siehe code) Java Basics - Anfänger-Themen 7
gamebreiti Verständnisfrage zu contains() Java Basics - Anfänger-Themen 10
A Verständnisfrage - Koordinatenumrechnung Java Basics - Anfänger-Themen 9
J Erste Schritte Verständnisfrage im Bezug auf das (richtige) Programmieren Java Basics - Anfänger-Themen 5
M Verständnisfrage zu JUnit Tests und private Methoden Java Basics - Anfänger-Themen 3
H Verständnisfrage Array Java Basics - Anfänger-Themen 2
I Interface Verständnisfrage Interfaces (Bsp.: Enumeration) Java Basics - Anfänger-Themen 2
I Verständnisfrage zu BridgePattern, Verwedung von super() Java Basics - Anfänger-Themen 4
P Verständnisfrage Java Basics - Anfänger-Themen 3
kaoZ Best Practice Verständnisfrage Listener bei lokalen Objekten Java Basics - Anfänger-Themen 8
D Input/Output Verständnisfrage Verzeichnis-/Dateiliste erstellen & Dateikonvertierung Java Basics - Anfänger-Themen 1
S Verständnisfrage zu Anweisungen und deren Wirkung Java Basics - Anfänger-Themen 7
H Verständnisfrage für oder Anweisung Java Basics - Anfänger-Themen 8
E Threads Verständnisfrage bzgl. Threads und Sleep Java Basics - Anfänger-Themen 2
T Erste Schritte Verständnisfrage: Getter und Setter Methoden Java Basics - Anfänger-Themen 3
H Verständnisfrage zu Java-Ausgabe Java Basics - Anfänger-Themen 3
S Verständnisfrage Java Basics - Anfänger-Themen 2
N Verständnisfrage Code Java Basics - Anfänger-Themen 8
B Verständnisfrage Java Basics - Anfänger-Themen 2
H Interface Comparable Verständnisfrage Java Basics - Anfänger-Themen 6
B Verständnisfrage Codezeile Java Basics - Anfänger-Themen 7
B Verständnisfrage:Beispielprogramm BlueJ Java Basics - Anfänger-Themen 3
M Kurze Verständnisfrage zu einer Java Aufgabe Java Basics - Anfänger-Themen 12
K Erste Schritte Kleine Verständnisfrage Java Basics - Anfänger-Themen 12
R Verständnisfrage Referenzvariablen in array Java Basics - Anfänger-Themen 3
M Verständnisfrage: Objekt erzeugen u. zuweisen Java Basics - Anfänger-Themen 16
M Verständnisfrage zu JPanel Java Basics - Anfänger-Themen 3
S Verständnisfrage: Exception Gebrauch Java Basics - Anfänger-Themen 2
R Verständnisfrage NPE Java Basics - Anfänger-Themen 5
M Verständnisfrage zur Zahlenumwandlung (Dezimal-->Dual) Java Basics - Anfänger-Themen 25
P Java Objekte - Verständnisfrage Java Basics - Anfänger-Themen 9
N Verständnisfrage zu folgendem Programm Java Basics - Anfänger-Themen 2
L Grundlegende Verständnisfrage Hasmap Referenzen Java Basics - Anfänger-Themen 4
S Verständnisfrage zu Interfaces Java Basics - Anfänger-Themen 2
VfL_Freak Verständnisfrage zur Klasse "TIMER" Java Basics - Anfänger-Themen 7
P Verständnisfrage zu Instanzen/Objekten Java Basics - Anfänger-Themen 9
M Verständnisfrage im Umgang mit Map Java Basics - Anfänger-Themen 10
K Verständnisfrage zu int.length und String.length() Java Basics - Anfänger-Themen 4
G 2D Array gleichsetzen verständnisfrage Java Basics - Anfänger-Themen 2
M kleine und einfache Verständnisfrage Java Basics - Anfänger-Themen 3
N verständnisfrage java.util.Calendar Java Basics - Anfänger-Themen 4
G Datentypen bits, bytes, chars - Verständnisfrage Java Basics - Anfänger-Themen 5
E Verständnisfrage zu Shutdownhook Java Basics - Anfänger-Themen 5
D Verständnisfrage: Java und MySql Java Basics - Anfänger-Themen 3
F Rekursion Verständnisfrage Java Basics - Anfänger-Themen 6
A Exception Verständnisfrage: Exceptions während, einer Statischenzuweisung abfangen Java Basics - Anfänger-Themen 10
Z Comparator Verständnisfrage Java Basics - Anfänger-Themen 5
D Verständnisfrage zu Funktionen Java Basics - Anfänger-Themen 6
H Verständnisfrage Persistenz Java Basics - Anfänger-Themen 10
neurox Verständnisfrage zu Threads Java Basics - Anfänger-Themen 4
E Verständnisfrage Syntax: frame.getContentPane().add(button) Java Basics - Anfänger-Themen 11
Y Kleine Verständnisfrage zum Thema dynamische Polymorphie Java Basics - Anfänger-Themen 3
F Verständnisfrage Objekt instanzierung / Polymorphie Java Basics - Anfänger-Themen 10

Ähnliche Java Themen

Neue Themen


Oben