今更だけどEnumでSingleton

Java1.5からEnum型が追加され、定数の定義等に利用されていますが、EffectiveJava久々に読み直していたら、EnumでSingletonをやるのがおしゃれさんだよと書いてあったので、ブログにメモしときます。
周知の事実すぎるので、今更かよ感ありますが、知らなかった人は明日からやってみてください。

Java1.5より昔は以下の様にSingletonにしていたと思います。ここでは遅延初期化とか、スレッドセーフかどうかとか、シリアライズで複製されちゃうじゃんとかそういうことは分かり難くなるので、省きます。そうすると、こんな感じですね。

package singleton;

public class TraditionalSingleton {
	private static final TraditionalSingleton INSTANCE = new TraditionalSingleton();

	private TraditionalSingleton(){}
	
	public static TraditionalSingleton getInstance(){
		return INSTANCE;
	}
	
	public void method(){
		System.out.println("this is singleton");
	}
}

それをEnumでやると以下のようになります。Enumで定数化したときに、コンパイルすると実際は、public static final hogeになっているので、結局は同じことなんですが、可読性及び、シリアライズに対応していたり、リフレクションによるprivateコンストラクタ実行への防御とか、モロモロいい感じにしてくれます。

package singleton;

public enum ModernSingleton {
	INSTANCE;
	
	public void method(){
		System.out.println("this is singleton");
	}
}

実行は以下。

TraditionalSingleton.getInstance().method();
ModernSingleton.INSTANCE.method();

今まで知らなかったのが恥ずかしい。