Implementación de Singleton con una enumeración (en Java)

Resuelto Anand asked hace 10 años • 6 respuestas

He leído que es posible implementar Singletonen Java usando algo Enumcomo:

public enum MySingleton {
     INSTANCE;   
}

Pero, ¿cómo funciona lo anterior? Específicamente, Objectse debe crear una instancia de an. Aquí, ¿cómo se MySingletoncrea una instancia? ¿ Quién está haciendo new MySingleton()?

Anand avatar Oct 10 '14 01:10 Anand
Aceptado

Este,

public enum MySingleton {
  INSTANCE;   
}

tiene un constructor vacío implícito. Hazlo explícito en su lugar,

public enum MySingleton {
    INSTANCE;
    private MySingleton() {
        System.out.println("Here");
    }
}

Si luego agregaste otra clase con un main()método como

public static void main(String[] args) {
    System.out.println(MySingleton.INSTANCE);
}

Tu verias

Here
INSTANCE

enumLos campos son constantes de tiempo de compilación, pero son instancias de su enumtipo. Y se construyen cuando se hace referencia al tipo de enumeración por primera vez .

Elliott Frisch avatar Oct 09 '2014 18:10 Elliott Frisch

Un enumtipo es un tipo especial de class.

En realidad , serás enumcompilado en algo como

public final class MySingleton {
    public final static MySingleton INSTANCE = new MySingleton();
    private MySingleton(){} 
}

Cuando su código acceda por primera vez INSTANCE, MySingletonla JVM cargará e inicializará la clase. Este proceso inicializa el staticcampo anterior una vez (perezosamente).

Sotirios Delimanolis avatar Oct 09 '2014 18:10 Sotirios Delimanolis

En este libro de mejores prácticas de Java de Joshua Bloch, puede encontrar una explicación de por qué debería aplicar la propiedad Singleton con un constructor privado o un tipo Enum. El capítulo es bastante largo, por lo que lo resumiré:

Hacer que una clase sea Singleton puede dificultar la prueba de sus clientes, ya que es imposible sustituir un singleton por una implementación simulada a menos que implemente una interfaz que sirva como su tipo. El enfoque recomendado es implementar Singletons simplemente creando un tipo de enumeración con un elemento:

// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}

Este enfoque es funcionalmente equivalente al enfoque de campo público, excepto que es más conciso, proporciona la maquinaria de serialización de forma gratuita y proporciona una garantía sólida contra la creación de instancias múltiples, incluso frente a ataques sofisticados de serialización o reflexión.

Si bien este enfoque aún no se ha adoptado ampliamente, un tipo de enumeración de un solo elemento es la mejor manera de implementar un singleton.

ekostadinov avatar Oct 10 '2014 06:10 ekostadinov

Como todas las instancias de enumeración, Java crea una instancia de cada objeto cuando se carga la clase, con cierta garantía de que se crea una instancia exactamente una vez por JVM . Piense en la INSTANCEdeclaración como un campo final estático público: Java creará una instancia del objeto la primera vez que se haga referencia a la clase.

Las instancias se crean durante la inicialización estática, que se define en la Especificación del lenguaje Java, sección 12.4 .

Por si sirve de algo, Joshua Bloch describe este patrón en detalle como el elemento 3 de Effective Java Second Edition .

Jeff Bowman avatar Oct 09 '2014 18:10 Jeff Bowman