He leído que es posible implementar Singletonen Java usando un Enumtal como:
public enum MySingleton {
INSTANCE;
}
Pero, ¿cómo funciona lo anterior? Específicamente, un Objecttiene que ser instanciado. Aquí, ¿cómo se MySingletonestá instanciando? ¿Quién está haciendo new MySingleton()?
java
design-patterns
enums
singleton
Anand
fuente
fuente

INSTANCEes igual quepublic static final MySingleton INSTANCE = new MySingleton();.Respuestas:
Esta,
tiene un constructor vacío implícito. Hazlo explícito en su lugar,
Si luego agregaste otra clase con un
main()método comoTu verias
enumlos campos son constantes de tiempo de compilación, pero son instancias de suenumtipo. Y, se construyen cuando se hace referencia al tipo de enumeración por primera vez .fuente
privatemodificador no tiene significado para unenumconstructor y es completamente redundante.Un
enumtipo es un tipo especial declass.Tu
enumrealmente será compilado a algo asíCuando su código accede por primera vez
INSTANCE, la claseMySingletonserá cargada e inicializada por la JVM. Este proceso inicializa elstaticcampo anterior una vez (perezosamente).fuente
public enum MySingleton { INSTANCE,INSTANCE1; }y luegoSystem.out.println(MySingleton.INSTANCE.hashCode()); System.out.println(MySingleton.INSTANCE1.hashCode());imprime diferentes códigos hash. ¿Significa que se crean dos objetos de MySingleton?enumconstantes de diferencia .En este libro de prácticas recomendadas de Java de Joshua Bloch, puede encontrar explicaciones de por qué debe aplicar la propiedad Singleton con un constructor privado o un tipo Enum. El capítulo es bastante largo, así que resumiéndolo:
Convertir una clase en Singleton puede dificultar la prueba de sus clientes, ya que es imposible sustituir una implementación simulada por un singleton a menos que implemente una interfaz que sirva como su tipo. El enfoque recomendado es implementar Singletons simplemente haciendo un tipo de enumeración con un elemento:
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 ofrece una garantía irrefrenable contra la creación de instancias múltiples, incluso frente a ataques sofisticados de serialización o reflexión.
fuente
Como todas las instancias de enumeración, Java crea instancias de cada objeto cuando se carga la clase, con cierta garantía de que se 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 lo que vale, Joshua Bloch describe este patrón en detalle como elemento 3 de Effective Java Second Edition .
fuente
Dado que Singleton Pattern se trata de tener un constructor privado y llamar a algún método para controlar las instancias (como algunos
getInstance), en Enums ya tenemos un constructor privado implícito.No sé exactamente cómo la JVM o algún contenedor controla las instancias de nuestro
Enums, pero parece que ya usa un implícitoSingleton Pattern, la diferencia es que no llamamos agetInstance, solo llamamos Enum.fuente
Como se ha mencionado, hasta cierto punto, una enumeración es una clase de Java con la condición especial de que su definición debe comenzar con al menos una "constante de enumeración".
Aparte de eso, y que las enumeraciones no pueden extenderse o usarse para extender otras clases, una enumeración es una clase como cualquier clase y la usa agregando métodos debajo de las definiciones constantes:
Accede a los métodos de singleton a lo largo de estas líneas:
El uso de una enumeración, en lugar de una clase, es, como se ha mencionado en otras respuestas, principalmente sobre una instanciación segura de subprocesos del singleton y una garantía de que siempre será solo una copia.
Y, quizás, lo más importante, que este comportamiento está garantizado por la propia JVM y la especificación Java.
Aquí hay una sección de la especificación de Java sobre cómo se evitan varias instancias de una instancia de enum:
Vale la pena señalar que después de la instanciación, cualquier problema de seguridad de subprocesos debe manejarse como en cualquier otra clase con la palabra clave sincronizada, etc.
fuente