![translation](https://cdn.durumis.com/common/trans.png)
Esta es una publicación traducida por IA.
[Effective Java] Artículo 3. Garantiza un singleton con un constructor privado o un tipo de enumeración
- Idioma de escritura: Coreano
- •
-
País de referencia: Todos los países
- •
- Tecnología de la información
Seleccionar idioma
Texto resumido por la IA durumis
- Un singleton es una clase que solo puede crear una instancia, que se utiliza para crear objetos sin estado o componentes únicos del sistema.
- Hay tres métodos para crear un singleton: un miembro público static que es un campo final, proporcionar un método de fábrica estático, y usar un tipo de enumeración; el método de tipo de enumeración es el más adecuado.
- Al serializar una clase singleton, debes implementar Serializable, declarar todos los campos de instancia como transient y sobrescribir el método readResolve().
Singleton
El concepto de Singleton
Un Singleton es una clase que solo puede crear una instancia. Un ejemplo típico de Singleton es un objeto sin estado o un componente de sistema único. Sin embargo, las clases Singleton son difíciles de probar si no se definen por tipo como una interfaz y se definen como su implementación.
Cómo crear un Singleton
Método en el que el miembro static es un campo final
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public void speak() {
System.out.println("elvis");
}
El constructor privado se llama solo una vez cuando se inicializa la instancia de Elvis, lo que garantiza que sea la única instancia en todo el sistema. Sin embargo, se puede llamar al constructor privado usando AccessibleObject.setAccessible(), pero este método de modificación usando reflexión se puede prevenir lanzando una excepción cuando se crea el segundo objeto.
- Ventajas
- Es obvio en la API que la clase es Singleton.
- Es conciso.
Método que proporciona un método de fábrica estático público
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public static Elvis getInstance() {
return INSTANCE;
}
public void speak() {
System.out.println("elvis");
}
Este método también garantiza que sea la única instancia en todo el sistema, excepto por modificaciones usando reflexión. El campo se cambia a private y el método de fábrica estático se usa para devolver el objeto.
- Ventajas
- Se puede cambiar a no Singleton sin cambiar la API.
- Por ejemplo, se puede configurar para que el método de fábrica estático devuelva diferentes instancias por hilo.
- Se puede cambiar a un método de fábrica de Singleton genérico si se desea.
- Se puede usar una referencia de método de fábrica estática como proveedor.
- Por ejemplo, en lugar de Elvis::getInstance, se puede usar Supplier<Elvis>.
- Se puede cambiar a no Singleton sin cambiar la API.
Si no necesitas usar las ventajas anteriores, es mejor usar el primer método.
Método usando un tipo de enumeración
public enum Elvis {
INSTANCE;
public void speak() {
System.out.println("elvis");
}
El método más recomendable es usar un tipo de enumeración. Es más seguro contra los ataques de reflexión y el código es más limpio que los dos métodos anteriores. Además, como se explica más adelante, los dos métodos anteriores tienen la desventaja de que se debe agregar código adicional al serializar.
Sin embargo, debes tener en cuenta que si bien es posible que el Singleton que deseas crear herede una interfaz, no puede heredar una clase.
Puntos a tener en cuenta al serializar una clase Singleton
Si quieres serializar una clase Singleton creada usando el primer o segundo método, debes implementar Serializable además de declarar todos los campos de instancia como transient y redefinir el método readResolve() para proporcionarlo.
private Object readResolve throws ObjectStreamException {
return INSTANCE;