Comme cela a, dans une certaine mesure, été mentionné précédemment, une enum est une classe java avec la condition spéciale que sa définition doit commencer par au moins une "constante enum".
En dehors de cela, et que les énumérations ne peuvent pas être étendues ou utilisées pour étendre d'autres classes, une énumération est une classe comme n'importe quelle classe et vous l'utilisez en ajoutant des méthodes sous les définitions de constante:
public enum MySingleton {
INSTANCE;
public void doSomething() { ... }
public synchronized String getSomething() { return something; }
private String something;
}
Vous accédez aux méthodes du singleton en suivant ces lignes:
MySingleton.INSTANCE.doSomething();
String something = MySingleton.INSTANCE.getSomething();
L'utilisation d'une énumération, au lieu d'une classe, est, comme cela a été mentionné dans d'autres réponses, principalement sur une instanciation thread-safe du singleton et une garantie qu'il ne sera toujours qu'une copie.
Et, peut-être, plus important encore, que ce comportement est garanti par la machine virtuelle Java elle-même et la spécification Java.
Voici une section de la spécification Java sur la façon dont plusieurs instances d'une instance enum sont empêchées:
Un type enum n'a pas d'instances autres que celles définies par ses constantes enum. La tentative d'instanciation explicite d'un type enum est une erreur de compilation. La méthode de clonage finale dans Enum garantit que les constantes d'énumération ne peuvent jamais être clonées, et le traitement spécial par le mécanisme de sérialisation garantit que les instances dupliquées ne sont jamais créées à la suite de la désérialisation. L'instanciation réfléchissante des types enum est interdite. Ensemble, ces quatre éléments garantissent qu'aucune instance d'un type enum n'existe au-delà de celles définies par les constantes enum.
Il convient de noter qu'après l'instanciation, tout problème de sécurité des threads doit être traité comme dans toute autre classe avec le mot-clé synchronized, etc.