2013-08-24 28 views
1

靜態初始化器由類加載器調用一次,這正是我想要的,但是在靜態代碼塊之外進行初始化更具可讀性(可辯論)。兩者有什麼不同?初始化變量與其聲明或靜態初始化之間有區別嗎?

private static final Map<MyEnum, Cheese> cheeseCache; 

    static { 
     parserCache = new EnumMap< MyEnum, String>(MyEnum.class){{ 
      for(MyEnum myEnum: MyEnum.values()){ 
       put(myEnum, new Cheese(myEnum)) ; 
      } 

     }}; 
    } 

或本:

private static final Map<Lab, LabResultParser> cheeseCache 
     = new EnumMap< MyEnum, String>(MyEnum.class){{ 
      for(MyEnum myEnum: MyEnum.values()){ 
       put(myEnum, new Cheese(myEnum)) ; 
      } 
     }}; 
+0

只是好奇,第二個編譯?變量聲明中的for循環? –

+0

@JunedAhsan是它在一個anoymous子類(雙大括號initalziation) – NimChimpsky

+1

使用javap來拆卸這兩個,看看它們有何不同。 –

回答

0

你的情況是沒有區別的,你沒有做任何的邏輯來決定什麼樣的價值應該被分配到靜態變量。

java tutorial

在其聲明中的字段值初始化時效果不錯 初始化值可用並且初始化可以 放在同一行。但是,這種初始化形式由於其簡單性而具有侷限性 。如果初始化需要一些邏輯(例如,對於 示例,錯誤處理或for循環來填充複雜數組),簡單的 賦值是不充分的。實例變量可以在 構造函數中初始化,其中可以使用錯誤處理或其他邏輯。對於 爲類變量提供相同的功能,Java編程 語言包括靜態初始化塊。

但是我會和靜態塊一起去,因爲如果需要,你將有一個額外的選項來圍繞你的初始化代碼在try/catch。假設在填充enumMap時出現問題的場景,如果異常不是邏輯上致命的,我仍然希望執行繼續。

3

它可以影響排序 - 例如,你可以有:

private static final int declaredFirst; 

private static final int declaredSecond = new Random.nextInt(); 

static { 
    declaredFirst = declaredSecond + 1; 
} 

的初始化以文本順序執行。當然,你可能只是宣佈declaredFirst秒:

private static final int declaredSecond = new Random.nextInt(); 
private static final int declaredFirst = declaredSecond + 1; 

我個人使用靜態初始化塊,我不能幹淨表達一個表達式的初始值。

哦,如果你在一個靜態初始化塊初始化,變量不能被視爲一個常量表達式:

private static final int THIS_IS_A_CONSTANT = 10; 
private static final int thisIsNotAConstant; 

static { 
    thisIsNotAConstant = 20; 
} 

public static void main(String[] args) { 
    System.out.println(THIS_IS_A_CONSTANT); // 10 is inlined 
    System.out.println(thisIsNotAConstant); // 20 is not inlined 
} 

這只是很少相關的,當然。

所以在大多數情況下,這只是個人選擇。你的情況當然,要使用多個語句的能力意味着你需要使用難看(IMO)「匿名內部類只是爲了得到一些初始化」:

private static final Map<MyEnum, Cheese> cheeseCache; 

static { 
    parserCache = new EnumMap<>(MyEnum.class); 
    for (MyEnum myEnum: MyEnum.values()) { 
     put(myEnum, new Cheese(myEnum)); 
    } 
} 
+0

噢,親愛的。不知道最後一部分。 +1。 –

+0

@RohitJain:我沒有想到它,直到我正在寫答案:) –

+0

OOPs,最後一部分現在成爲第二個最後部分。那個談論常量的人。 –

1

您的片段的兩個創建僅僅爲了初始化而擴展EnumMap的一種不良內在類。簡單地委託給一個方法會更簡潔:

private static final Map<MyEnum, Cheese> CHEESE_CACHE = createCheeseCache(); 

private static Map<MyEnum, Cheese> createCheeseCache() { 
    EnumMap<MyEnum, Cheese> result = new EnumMap<MyEnum, Cheese>(MyEnum.class); 
    for (MyEnum myEnum: MyEnum.values()){ 
     result.put(myEnum, new Cheese(myEnum)) ; 
    } 
    return result; 
}