2012-10-02 5 views
14

Was ist der richtige Weg, um Java-Enum-basierte Singleton zu initialisieren, wenn ich es initialisieren muss, bevor ich das Objekt verwenden kann.Wie initialisiert Java Enum-basierte Singleton?

Ich habe angefangen, den Code zu schreiben, aber ich bin mir nicht sicher, ob ich es richtig mache. Könntest du mir helfen, dieses Singleton korrekt für mich zu implementieren?

public enum BitCheck { 

    INSTANCE; 

    private static HashMap<String, String> props = null; 

    public synchronized void initialize(HashMap<String, String> properties) { 
     if(props == null) { 
      props = properties; 
     } 
    } 

    public boolean isAenabled(){ 
     return "Y".equalsIgnoreCase(props.get("A_ENABLED")); 
    } 

    public boolean isBenabled(){ 
     return "Y".equalsIgnoreCase(props.get("B_ENABLED")); 
    } 

} 
+0

Ich mag das nicht, was versuchst du zu erreichen? – zengr

+0

Warum benötigen Sie eine Enum mit nur einem Element, wenn Sie bereits ein Singleton verwenden? – Dunes

+0

@Dunes Ich möchte ein Singleton, damit ich es in meiner Codebasis verwenden kann, um Werte zu überprüfen. Ich werde beim Start mit den Eigenschaften initialisieren und verwende die Prüfmethoden im gesamten Projekt. –

Antwort

30

Es ist durchaus möglich ist, Konstruktor zu erstellen für enum:

public enum BitCheck { 

    INSTANCE; 

    BitCheck() { 
     props = new HashMap<String, String>(); 
    } 

    private final Map<String, String> props; 

    //.. 

} 

Beachten Sie, dass:

  • props Feld endgültig sein kann (wir final mögen)
  • props hat nicht zu sein static
  • Konstruktor heißt automatisch und eifrig für Sie

Achten Sie auf den letzten Punkt. Da enum -Singlets eifrig erstellt werden, wenn die enum BitCheck-Klasse geladen wird, haben Sie keine Möglichkeit, Argumente an den Konstruktor zu übergeben. Natürlich können Sie INSTANCE Erklärung durch:

public enum BitCheck { 

    INSTANCE(new HashMap<String, String>()); 

    BitCheck(final Map<String, String> props) { 
     this.props = props; 
    } 

aber dies keinen Unterschied macht, nicht wahr? Was willst du erreichen? Vielleicht brauchen Sie tatsächlich faul initialisiertes Singleton?

+0

Ich denke, es wird eine schlechte Idee sein, so zu erstellen, da Konstruktor nichts Gutes bietet. Es kann einfache Deklaration sein –

+0

Ich möchte mit einer Reihe von Werten initialisieren, die ich an den Singleton übergeben möchte. Wie kann ich das machen? Ihr Beispiel initialisiert mit leerer hashmap. –

+1

@java_mouse: das ist die Sache. Es gibt keine Möglichkeit, etwas von außen an den Konstruktor zu übergeben, 'enum' Singleton wird dir nicht helfen. –

1
public enum BitCheck { 

    INSTANCE; 

    private BitCheck() { 
     // initialize here 
    } 

} 
5

Sie müssen es nur in Deklaration initialisieren.

public enum BitCheck { 
    INSTANCE; 
    private final Map<String, String> props = new ConcurrentHashMap<String, String>(); 

    public void putAll(HashMap<String, String> map) { 
     props.putAll(map); 
    } 
} 
+0

+1, sollten Sie irgendwie "Requisiten" synchronisieren. –

+0

Yup. Danke hat es geändert. –

0

Sie können so etwas in Ihrem Enum-basierten Singleton-Code versuchen. Dadurch wird sichergestellt, dass der Singleton genau einmal initialisiert werden kann.

private static Properties props; 
private static AtomicBoolean isInitialized = new AtomicBoolean(false); 

public void init(Properties props){ 
    if(isInitialized.compareAndSet(false, true)) { 
     this.props = props; 
    } 
} 

HINWEIS: Für komplexere Initialisierung, würden Sie 2 AtomicBooleans für initStarted und initCompleted müssen (statt einzelner AtomicBoolean - isInitialized). Dann setzt der erste Thread initStarted und führt die Initialisierungsschritte aus, der Rest wartet, bis initCompleted vom ersten Thread auf true gesetzt wird.

Verwandte Themen