2012-10-02 20 views
14

¿Cuál es la forma correcta de inicializar el singleton basado en Java enum, si tengo que inicializarlo antes de poder usar el objeto?¿Cómo inicializar el singleton basado en Java?

He comenzado a escribir el código, pero no estoy seguro si lo estoy haciendo bien. ¿Podrías ayudarme a implementar este singleton correcto para mí?

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

No me gusta esto, ¿qué intentas lograr? – zengr

+0

¿Por qué necesita una enumeración con solo un elemento cuando ya está utilizando un singleton? – Dunes

+0

@Dunes Quiero un singleton para que pueda usar esto en mi base de código para verificar los valores. Comenzaré con las propiedades durante el inicio y usaré los métodos de verificación en todo el proyecto. –

Respuesta

30

Es perfectamente posible crear constructor para enum:

public enum BitCheck { 

    INSTANCE; 

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

    private final Map<String, String> props; 

    //.. 

} 

Tenga en cuenta que:

  • props campo puede ser final (nos gusta final)
  • props No tiene ser static
  • constructor se llama automáticamente y con entusiasmo para usted

Preste atención al último punto. Como enum -singletons se crean con entusiasmo cuando se carga la clase enum BitCheck, no tiene forma de pasar ningún argumento al constructor. Por supuesto que puede a través de INSTANCE declaración:

public enum BitCheck { 

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

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

pero esto no hace ninguna diferencia, ¿verdad? ¿Qué quieres lograr? ¿Tal vez realmente necesitas un singleton con inicialización lenta?

+0

Supongo que será mala idea crear así porque el constructor no ofrece nada bueno. Puede ser simple declaración –

+0

Quiero inicializar con un conjunto de valores, que quiero pasarlo al singleton. ¿Cómo puedo hacer eso? Tu ejemplo se está inicializando con hashmap vacío. –

+1

@java_mouse: esa es la cosa. No hay forma de pasarle nada al constructor desde afuera, 'enum' singleton no lo ayudará. –

1
public enum BitCheck { 

    INSTANCE; 

    private BitCheck() { 
     // initialize here 
    } 

} 
5

Tiene que inicializarlo en la declaración.

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, debe sincronizar 'props' de alguna manera. –

+0

Sí. Gracias lo cambió. –

0

Puede probar algo como esto dentro de su código de Singleton basado en Enum. Esto asegurará que Singleton se pueda inicializar exactamente una vez.

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

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

NOTA: Para la inicialización más complejo, se necesitaría 2 AtomicBooleans para initStarted y initCompleted (en lugar de una sola AtomicBoolean - isInitialized). Luego, el primer subproceso establece initStarted y ejecuta los pasos de inicialización, el resto espera hasta que initCompleted se establezca en verdadero por el primer subproceso.

Cuestiones relacionadas