Quelle est la meilleure approche pour utiliser un Enum comme singleton en Java?

85

S'appuyant sur ce qui a été écrit dans la question SO Meilleure implémentation de singleton en Java - à savoir sur l'utilisation d'un enum pour créer un singleton - quelles sont les différences / avantages / inconvénients entre (constructeur omis)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

puis appeler Elvis.INSTANCE.getAge()

et

public enum Elvis {
    INSTANCE;
    private int age;

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

puis appeler Elvis.getAge()

Miles D
la source

Réponses:

96

Supposons que vous vous liez à quelque chose qui utilisera les propriétés de n'importe quel objet qui lui est donné - vous pouvez passer Elvis.INSTANCE très facilement, mais vous ne pouvez pas passer Elvis.class et vous attendre à ce qu'il trouve la propriété (à moins qu'il ne soit délibérément codé pour trouver propriétés statiques des classes).

Fondamentalement, vous n'utilisez le modèle singleton que lorsque vous voulez une instance. Si les méthodes statiques fonctionnent bien pour vous, utilisez-les simplement et ne vous embêtez pas avec l'énumération.

Jon Skeet
la source
1
Pourquoi ne pas s'embêter avec l'énumération? Existe-t-il une meilleure façon de faire des singeltons en java5 +?
jontro
4
@jontro (re) lit la réponse; il dit d'utiliser des énumérations lorsque vous devez avoir un singleton mais d'éviter le singleton si vous pouvez vous contenter de méthodes statiques
Variable misérable
@MiserableVariable J'ai commenté cela il y a plus d'un an. Je ne me souviens pas vraiment du contexte auquel je faisais référence.
jontro
ne répond pas à la question posée
Thufir
2
@Thufir: Il répond à la partie "quelle est la différence" - qui semble être ce qui intéressait le plus le PO, étant donné que la réponse a été acceptée.
Jon Skeet
69

Un grand avantage est lorsque votre singleton doit implémenter une interface. En suivant votre exemple:

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

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

Avec:

public interface HasAge {
    public int getAge();
}

Cela ne peut pas être fait avec la statique ...

Nicolas
la source
1
Cela peut être fait avec la statique ... public static final HasAge INSTANCE = new HasAge () {private int age; @Override public int getAge () {return age; }}; ... donc je me demande toujours ce qui est bon ou meilleur dans la méthode enum. Je suppose que si vous aviez besoin d'implémenter deux interfaces?
Sean Adkinson
9

(Avec état) Les singletons sont généralement utilisés pour faire semblant de ne pas utiliser de variables statiques. Si vous n'utilisez pas réellement la variable publiquement statique, vous tromperez moins de gens.

Tom Hawtin - Tacle
la source
8

Je choisirais l'option qui est la plus simple et la plus claire. C'est quelque peu subjectif, mais si vous ne savez pas ce qui est le plus clair, optez pour l'option la plus courte.

Peter Lawrey
la source