9

これはおかしなエラーのようですが、Enum.valueOf(type, name)Oracle JDK 7 SE では不安定なようです。

明示的には、まったく同じ名前の String (私はこれを確認しました) で、 への呼び出しがメッセージとともにvalueOf()スローされることがあります。IllegalArgumentExceptionNo 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() を返していることを明確に示しています。

デバッガ式

4

2 に答える 2