Qual é a melhor abordagem para usar um Enum como um singleton em Java?

85

Com base no que foi escrito na questão SO, a melhor implementação de singleton em Java - especificamente sobre o uso de um enum para criar um singleton - quais são as diferenças / prós / contras entre (construtor omitido)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

e então ligando Elvis.INSTANCE.getAge()

e

public enum Elvis {
    INSTANCE;
    private int age;

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

e então ligando Elvis.getAge()

Milhas D
fonte

Respostas:

96

Suponha que você esteja vinculado a algo que usará as propriedades de qualquer objeto fornecido - você pode passar Elvis.INSTANCE muito facilmente, mas não pode passar Elvis.class e esperar que ele encontre a propriedade (a menos que seja deliberadamente codificado para encontrar propriedades estáticas das classes).

Basicamente, você só usa o padrão singleton quando deseja uma instância. Se os métodos estáticos funcionarem bem para você, use-os e não se preocupe com o enum.

Jon Skeet
fonte
1
Por que não se preocupar com o enum? Existe uma maneira melhor de fazer singeltons em java5 +?
Jontro
4
@jontro (re) leia a resposta; ele diz para usar enums quando você deve ter um singleton, mas para evitar singleton se você puder se contentar com métodos estáticos
Variável miserável
@MiserableVariable Comentei sobre isso há mais de um ano. Não consigo me lembrar de qual contexto eu estava me referindo.
Jontro
não responde à pergunta feita
Thufir 02/09/2013
2
@Thufir: Responde à parte "qual é a diferença" - que parece ser o que mais interessou ao OP, visto que a resposta foi aceita.
Jon Skeet,
69

Uma grande vantagem é quando seu singleton deve implementar uma interface. Seguindo seu exemplo:

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

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

Com:

public interface HasAge {
    public int getAge();
}

Não pode ser feito com estática ...

Nicolas
fonte
1
Isso pode ser feito com estática ... public static final HasAge INSTANCE = new HasAge () {private int age; @Override public int getAge () {idade de retorno; }}; ... então, ainda estou me perguntando o que é bom ou melhor no método enum. Suponho que se você precisasse implementar duas interfaces?
Sean Adkinson
9

(Stateful) Singletons geralmente são usados ​​para fingir que não estão usando variáveis ​​estáticas. Se você realmente não usar a variável publicamente estática, enganará menos pessoas.

Tom Hawtin - tackline
fonte
8

Eu escolheria a opção mais simples e clara. Isso é um tanto subjetivo, mas se você não sabe o que é mais claro, escolha a opção mais curta.

Peter Lawrey
fonte