enum によるより良い Singleton

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;
    }
}