静的変数の初期化順序と問題


まずコードを見て、何が出力されるか当ててみましょう.
public  class Elvis{
	public static final Elvis INSTANCE=new Elvis();
	private static final int CURRENT_YEAR=Calendar.getInstance().get(Calendar.YEAR);
	private final int beltSize;
	private Elvis(){
		beltSize=CURRENT_YEAR-1930;
	}
	private int beltSize(){
		return beltSize;
	}
	
	public static void main(String args[]){
		System.out.println("Elvis wears a size : "+INSTANCE.beltSize()+" belt.");
	}
}

今年は2014年なので、beltSizeの結果は84(2014-1930)と思われるかもしれません.しかし、事実はbeltSizeが-193であることを証明している.
原因分析:public static final Elvis INSTANCE=new Elvis()を実行する.コンストラクション関数の場合、CURRENT_YEARは0になったのでbeltSizeは-193になりました.
 
実は2つの文の順序を交換すれば済むので,クラス初期化ループの問題を解決する.
private static final int CURRENT_YEAR=Calendar.getInstance().get(Calendar.YEAR);
public static final Elvis INSTANCE=new Elvis();