これはおかしなエラーのようですが、Enum.valueOf(type, name)
Oracle JDK 7 SE では不安定なようです。
明示的には、まったく同じ名前の String (私はこれを確認しました) で、 への呼び出しがメッセージとともにvalueOf()
スローされることがあります。IllegalArgumentException
No enum constant ...
enumConstantDirectory()
私のチームはこれを Eclipse デバッガーで実行しました。次の JDK 実装の enum 、つまり enum のvalues()
リストで、いくつかの値が欠落しているように見えることに気付きました。列挙型自体で定義されたすべての値の全体ではありません。
Enum.valueOf(enumclass.class, "XXX")
JVM の起動時に可能なすべての列挙値を呼び出すことで、このバグを回避できます。これを行うと、values()
常にフルセットが含まれているようです。
ただし、このタイプの初期化を行わないとEnum.valueOf()
、IllegalArgumentException
.
コンテキスト: XStream 1.4.4 を使用して enum を変換する POJO オブジェクトを変換するときにこの問題が発生しますが、この問題は本質的に XStream にあるようには見えません。
誰もこの種のエラーを見たことがありますか? もしあれば、それについて聞いてみたいです。それは私の心を揺さぶります。これは Oracle JDK/JVM 実装のバグですか?
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
その他の関連する詳細:
ライブラリを使用して、org.reflections
起動時にコード内のすべての列挙型をスキャンしています。スキャン中に、列挙型の型を取得し、列挙型にclazz.getEnumConstants()
関連付けられた Class オブジェクトを呼び出します。これは関連する詳細かもしれません。
見た目とjava.lang.Class.getEnumConstants()
実装ではenumConstants
、クラス内で同じ共有オブジェクトを共有しているようです。ここの実装に問題があるのだろうか。
私たちの列挙型は非常にシンプルで、静的な初期化などはありません.
public enum ScreeningRuleType
{
INSERT,
CONFIRMATION,
AMOUNT,
EXISTENCE,
BAN,
SELECTION,
CUSTOM;
private long id;
private String descr;
ScreeningRuleType()
{
id = this.ordinal();
descr= this.toString().replace("_", " ");
}
}
編集: これを実験する中で、私は別の兆候を見つけています。System.out 初期化を使用した後、IllegalArgumentException をスローする代わりに、Enum.valueOf によって返される値がランダムに見えるようになりました。
これは、Eclipse デバッガーで見ているものを示しています。文字列 "EXISTENCE" と "EXISTENCE".intern() に対して valueOf() を呼び出していることを明確に示しており、代わりに AMOUNT() を返していることを明確に示しています。