这似乎是一个疯狂的错误,但是Enum.valueOf(type, name)在Oracle JDK 7 SE上似乎不稳定。

表现形式是,使用完全相同的名称String(我已经证实了这一点),对valueOf()的调用有时会抛出IllegalArgumentException和消息No enum constant ...

我的团队通过Eclipse调试器进行了此操作,我们注意到在枚举的valueOf的以下JDK实现中,enumConstantDirectory()(即枚举的values()列表)有时似乎缺少一些值。并不是枚举本身定义的所有值的全部。

我可以通过在JVM启动时为所有可能的枚举值调用Enum.valueOf(enumclass.class, "XXX")来解决该错误。当我这样做时,values()似乎总是包含完整的集合。

但是,如果我不进行此类初始化,则Enum.valueOf()有时会抛出IllegalArgumentException

上下文:使用XStream 1.4.4转换转换枚举的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()实现中,似乎在Class中共享相同的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初始化之后,现在由Enum.valueOf返回的值似乎是随机的,而不是引发IllegalArgumentException。

这显示了我在Eclipse调试器中看到的内容。它清楚地表明我正在字符串“EXISTENCE”和“EXISTENCE” .intern()上调用valueOf(),并清楚地表明它正在返回AMOUNT()。

最佳答案

我忘记了遇到类似情况的地方-但是我怀疑它是Java 7之前的版本,可能已经回到Java 4/5的日子了。

问题在于,仅在第一次访问enum中的一个时才触发与enum一起的伴随结构的构造。不幸的是,如果您在访问valueOf之一之前调用了依赖于这些结构的方法之一(例如EnumSet.allOfenum),则通常会导致灾难性的失败。

可悲的是,我重构了代码,这样就不会发生,因此我不再需要提供示例了。我将尝试重现该问题并与您联系。

我在这里看到-Why the Java enum constants initialization is not complete?发生了另一起带有演示的问题。

关于java - JDK 7 SE的Enum.valueOf错误,其中.values()损坏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16307844/

10-12 18:14