以前にある程度言及したように、列挙型は、その定義が少なくとも1つの「列挙型定数」で始まる必要があるという特別な条件を持つJavaクラスです。
それとは別に、列挙型を拡張したり他のクラスを拡張するために使用したりすることはできません。列挙型は他のクラスと同様のクラスであり、定数定義の下にメソッドを追加して使用します。
public enum MySingleton {
INSTANCE;
public void doSomething() { ... }
public synchronized String getSomething() { return something; }
private String something;
}
次のようにシングルトンのメソッドにアクセスします。
MySingleton.INSTANCE.doSomething();
String something = MySingleton.INSTANCE.getSomething();
クラスの代わりに列挙型を使用することは、他の回答で述べたように、主にシングルトンのスレッドセーフなインスタンス化と、常に1つのコピーだけになることの保証についてです。
そして、おそらく最も重要なこととして、この動作はJVM自体とJava仕様によって保証されています。
enumインスタンスの複数のインスタンスがどのように防止されるかについてのJava仕様のセクションを次に示します。
列挙型には、その列挙定数で定義されたもの以外のインスタンスはありません。列挙型を明示的にインスタンス化しようとすると、コンパイル時エラーになります。Enumの最後のcloneメソッドは、enum定数が複製されないようにし、シリアル化メカニズムによる特別な処理により、逆シリアル化の結果として重複インスタンスが作成されないようにします。列挙型の反射的なインスタンス化は禁止されています。これらの4つの要素により、列挙型のインスタンスが列挙型定数で定義されたインスタンスを超えて存在しないことが保証されます。
注目に値するのは、インスタンス化後、スレッドの安全性に関する懸念は、他のクラスと同様に、synchronizedキーワードなどで処理する必要があることです。