これは奇妙なエラーのようですが、Enum.valueOf(type, name)
はOracle JDK 7 SEでは不安定に見えます。Enum.valueOf .values()が壊れてしまうJDK 7 SEのバグ
正確に同じ名前の文字列(これを確認した)で、valueOf()
を呼び出すと、メッセージNo enum constant ...
でIllegalArgumentException
がスローされることがあります。
私のチームはEclipseデバッガーでこれを実行しました。次のJDK実装のvalueOfの値はenumConstantDirectory()
です。すなわち、values()
の列挙型のリストは時々値が欠落しているようです。列挙型自体で定義されたすべての値の全体ではありません。
JVMの起動時にすべての可能な列挙値に対してEnum.valueOf(enumclass.class, "XXX")
を呼び出すことで、このバグを回避できます。これを行うと、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
ライブラリを使用しています。スキャン中に列挙型を取得し、列挙型に関連付けられたClassオブジェクトに対してclazz.getEnumConstants()
を呼び出します。これは関連する詳細かもしれません。
実装では、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()が返されていることを明確に示しています。
間欠障害が発生することがあります。何か目立つパターンがありますか?どのくらいの頻度で失敗するのですか? – Zyerah
送信している文字列に埋め込みヌルが含まれている可能性はありますか?そのような場合は、正しい定数を選択していない可能性があります。 –
いくつかのコードパスでのみ失敗しますが、そのコードパスで再現できます。単体テストの開始時にSystem.out.println(Enum.valueOf(type、 "xxx"))にコード行を追加するだけで、エラーはなくなります。 – zzhu8192