これは、永続的な「長いifまたはスイッチ」のジレンマのバリエーションです...
長い(ダース以上の条件)ステートメントを含む静的メソッドを使用するマルチスレッドアプリケーションについて考えてみます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()
です。つまり、次のようなことを行います。
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
オブジェクトの使用にも当てはまり、おそらくこれら2つの選択肢は、enum.valueOf()
明らかにに基づいているため、同じパターンのバリアントです。
Enum.valueOf(Class<T> enumType, String name)
これは
enumType.enumConstantDirectory().get(name);
Class.java
クラスで。
このenumConstantDirectory()
メソッドは、呼び出されるたびに、配列HashMap
のコピーから作成された新しいを返します。values()
それはスレッドセーフでしょうか?