這是perpertual 「冗長-if或switch」困境的變化......線程安全
使用包含長一個靜態方法(超過一打的考慮多線程應用程序條件)if
語句,這相應地將檢查對象的類型,並返回一個值,即像
public static String checkType(Class<?> type)
{
if (type == A.class)
{
return aString;
}
else if (type == B.class)
{
return bString;
}
...
else if (type == z.class)
{
return zString;
}
}
顯然switch語句是不能直接適用在這裏,所以共同的圖案是有一個enum
並調用它valueOf()
,即d ø類似
public enum Strings
{
A(aString), B(bString), ..., Z(zString)
private final String value;
private Strings(String value)
{
this.value = value;
}
public String value()
{
return this.value;
}
}
所以,checkType()
可以重新寫爲
public static String checkType(Class<?> type)
{
return Strings.valueOf(getActualTypeName(type.getClass().getName())).value();
}
具有用於在生產代碼和非原始類型一些字符串處理加入null
值相應的檢查,則getActualTypeName()
方法內,從"class java.lang.Long"
等字符串中檢索實際的類型名稱(對於基元,getName()
方法返回期望的字符串,例如「long"
)。
但是,如果valueOf()
不是線程安全的,這不會在並行環境下工作。這同樣適用於使用(正常)Map
對象,可能這兩個選擇都是相同的模式的變種,因爲enum.valueOf()
顯然是基於
Enum.valueOf(Class<T> enumType, String name)
這就要求
enumType.enumConstantDirectory().get(name);
在
Class.java
類
。
每次調用enumConstantDirectory()
方法時,都會返回一個新的HashMap
,它由values()
數組的副本創建。
這是線程安全嗎?
如果它擴展Enum.valueOf() ,那麼它查找非同步映射。查看Enum.valueOf()方法的來源;它調用enumType.enumConstantDirectory()。get(name)。 – PNS 2012-08-16 12:44:05
@PNS如果你看得更深一些,你會看到'enumConstantDirectory'(變量)是易變的,所以這提供了足夠的保證,以確保映射安全地發佈,並且在構建之後永遠不會改變。最糟糕的情況是地圖不止一次被創建,但是因爲它的創建基於最終狀態,所以它是確定性的,所以所使用的懶惰模式使得它是線程安全的。 – assylias 2012-08-16 12:47:03
你是對的,它似乎是安全的。哪個好! :-) – PNS 2012-08-16 12:54:00