Wann werden Singletons während des Programms constructed?

Ich möchte nämlich bei einem Spiel einen Ladebildschirm erstellen und nutzte einige Singletons (gerade was IO-Daten angeht, die mehrfach von überall geholt werden müssen). Nun hat sich mir die Frage gestellt, wann Singletons denn während der Laufzeit erstellt werden, sodass ich diese auch gleich beim Loader erstellen kann.

mfg
BH16

PS: sry, falsches Unterforum, bin noch ans alte java-forum.org gewöhnt :slight_smile:

Wie sieht dein Singleton aus? Davon haengt das ab.

Ansonsten sollten wir ne Diskussion ueber den Sinn und Unsinn von Singletons an sich starten.

Schon mal mit Guice beschaeftigt? :smiley:

Naja, “constructed” werden Klasseninstanzen natürlich bei Aufruf des Constructors… Geladen werden Klassen aber normalerweise on demand, also erst dann wenn sie (zum ersten mal) verwendet werden.

Wenn ich mich richtig erinnere wird beim Laden einer Klasse ihr static initialization block ausgeführt. Das könntest du nutzen um herauszufinden wann sie geladen wird. Vielleicht hilft dir das schon etwas weiter.

public class Singelton {
    static {
        System.out.println("Klasse Singelton geladen");
        // hier kann man initialisationen unterbringen
        System.out.println("Klasse Singelton initialisiert");
    }
}

DowJones genauso ist es. Ich habe es getestet und es wird geladen, sobald ich die Klasse das erste mal aufrufe wird sie erstellt. Danke!

schalentier, nein habe ich nicht, und ich weiß nciht, ob ich das will :slight_smile:

mfg
BH16

Damn solltest du das mal tun :wink:

Nun hat sich mir die Frage gestellt, wann Singletons denn während der Laufzeit erstellt werden

Am besten gar nicht :wink:

Zeig doch mal eines deiner Singletons, bin mir sicher wir finden da den einen oder anderen Wurm drinnen…

Na gut, wenn ihr wollt… :slight_smile:

	private static final MapList instance = new MapList();
	private HashMap<String, Map> maps = new HashMap<String, Map>();
	private Map currentMap;
	
	private MapList() {
		File[] files = new File("res/maps/").listFiles();
		for (int i = 0; i < files.length; i++) {
			Map map = MapIO.read(files**);
			if (map.getStartPosX1().length == 0) {
				JOptionPane.showMessageDialog(null, "No start area for the teams defined. Please define them in the MapEditor.", "", JOptionPane.ERROR_MESSAGE);
			}
			maps.put(map.getName(), map);
		}
	}
	
	public static MapList getInstance() {
		return instance;
	}
	
	public String[] getMapNames() {
		Object[] o = maps.keySet().toArray();
		String[] s = new String[o.length];
		for (int i = 0; i < o.length; i++) {
			s** = (String) o**;
		}
		return s;
	}
	
	public Map getMap(String s) {
		currentMap = maps.get(s);
		return currentMap;
	}
	
	public Map getCurrentMap() {
		return currentMap;
	}
}```

Es wird halt eine MapList erstellt mit allen maps, die es gibt. Diese MapList muss von überall aus erreichbar sein, weil sie an verschiedensten Stellen, die nichts voneinander wissen, benötigt wird.

mfg
BH16

Naja, zumindest keine Lazy-Init, und damit keine Multithreading Probleme… :wink:

Das wäre IMHO ein sehr gutes Beispiel für DI, u.a. deswegen:

Diese MapList muss von überall aus erreichbar sein, weil sie an verschiedensten Stellen, die nichts voneinander wissen, benötigt wird.

Die „gute“ alte gloable Variable…
Das hast du zwar ohne DI erreicht, aber auf kosten der Testbarkeit wegen der Kopplung.

Durch die statische Kopplung zur getInstance Methode müsstest du jetzt tricksen beim Mocken (statische felder mocken), da geht natürlich mittlerweile, ist aber aufwendiger als mit DI.
Dazu kommt, dass MapList jetzt nicht nur zugriff auf die einzelnen Maps bietet, sondern sich auch für die Erzeugung und den Zugriff auf die MapList selber verantwortlich ist, d.h. SoC (Seperation of Concerns).

Nebenbei, das mit dem JOptionPane finde ich nicht gut an dieser Stelle, Exception werfen und den äusseren Kontext diese behandeln lassen wäre ein Möglichkeit ,aber ich glaube hier reicht es einfach wenn nix gemacht wird und wieder der Aufrufer (= äuserer Kontext) auf die leeren MapList reagiert.
Damit hätte deine MapList auch keine Kopplung zu Swing :wink:

Kann den Tipp mit Guice nur wiederholen, wenn man sich mal mit dem Themen Design, Architektur, Testen etc. pp. auseinandergesetzt und DI verstanden hat, wird man nicht mehr ohne wollen, nicht ohne Grund.

Das Video ansehen reicht meist schon dass man versteht wo die Vorteile leigen.

Ach ja, hier ist was Erich Gamma selber zu Singletons sagt:

Es geht IMHO nicht darum, dass das Singleton als „das böseste Anti-Pattern“ der Welt ist, sondern darum, dass Leute die das nutzen einfach nur einen Hammer haben und die Alternativen ignorieren… :wink:
Ich finde da sollte man seinen Werkzeugkasten erweitern und mit den neuen Dingen üben.

Vor allem macht DI aber Spass und Tests schreiben wird einfacher :slight_smile:

Wenn man dann DI und Tests draufhat, kann man sich mal an TDD wagen… aber dass kommt später :wink: