¿Cuál es el mejor enfoque para usar un Enum como singleton en Java?

85

Sobre la base de lo que se ha escrito en la pregunta SO Mejor implementación de singleton en Java , es decir, sobre el uso de una enumeración para crear un singleton, ¿cuáles son las diferencias / pros / contras entre (constructor omitido)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

y luego llamando Elvis.INSTANCE.getAge()

y

public enum Elvis {
    INSTANCE;
    private int age;

    public static int getAge() {
        return INSTANCE.age;
    }
}

y luego llamando Elvis.getAge()

Millas D
fuente

Respuestas:

96

Suponga que se está vinculando a algo que usará las propiedades de cualquier objeto que se le proporcione; puede pasar Elvis.INSTANCE muy fácilmente, pero no puede pasar Elvis.class y esperar que encuentre la propiedad (a menos que esté codificado deliberadamente para encontrar propiedades estáticas de las clases).

Básicamente, solo usa el patrón singleton cuando desea una instancia. Si los métodos estáticos funcionan bien para usted, entonces utilícelos y no se moleste con la enumeración.

Jon Skeet
fuente
1
¿Por qué no molestarse con la enumeración? ¿Hay una mejor manera de hacer singeltons en java5 +?
jontro
4
@jontro (re) leer la respuesta; dice que use enumeraciones cuando debe tener un singleton, pero para evitar singleton si puede arreglárselas con métodos estáticos
Variable miserable
@MiserableVariable Comenté esto hace más de un año. Realmente no recuerdo a qué contexto me refería.
jontro
no responde la pregunta formulada
Thufir
2
@Thufir: Responde a la parte de "cuál es la diferencia", que parece ser lo que más le interesó al OP, dado que la respuesta fue aceptada.
Jon Skeet
69

Una gran ventaja es cuando su singleton debe implementar una interfaz. Siguiendo tu ejemplo:

public enum Elvis implements HasAge {
    INSTANCE;
    private int age;

    @Override
    public int getAge() {
        return age;
    }
}

Con:

public interface HasAge {
    public int getAge();
}

No se puede hacer con estática ...

Nicolas
fuente
1
Se puede hacer con estática ... public static final HasAge INSTANCE = new HasAge () {private int age; @Override public int getAge () {edad de retorno; }}; ... así que todavía me pregunto qué es bueno o mejor sobre el método enum. ¿Supongo que si necesitara implementar dos interfaces?
Sean Adkinson
9

Los singleton (con estado) se utilizan generalmente para fingir que no se utilizan variables estáticas. Si en realidad no usa la variable públicamente estática, engañará a menos personas.

Tom Hawtin - tackline
fuente
8

Elegiría la opción más simple y clara. Esto es algo subjetivo, pero si no sabe qué es lo más claro, elija la opción más corta.

Peter Lawrey
fuente