Java 1.5 から導入されたenumにより安全なSingletonが作成可能。元ネタはEffective Javaだっけか? 実装はこんな感じ。
import java.util.concurrent.atomic.AtomicLong; public enum Singleton { INSTANCE; private AtomicLong counter = new AtomicLong(); public Long countUp() { return counter.incrementAndGet(); } public Long getCount() { return counter.get(); } }
動作確認
import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; import org.junit.Test; public class SingletonTest { @Test public final void testCountUp() { Singleton counter1 = Singleton.INSTANCE; assertThat(counter1.countUp(), is(1L)); assertThat(counter1.countUp(), is(2L)); assertThat(Singleton.INSTANCE.countUp(), is(3L)); } }
これにより、シリアライズやリフレクションにより、意図しないインスタンスが作成されることはなくなる。現在では、Singletonの定義は、enumによる上記が最善の方法。古いJavaであれば以下のようになるが、シリアライズやリフレクションに対する防御が必要。
public class Singleton { private static Singleton _instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return _instance; } }