这似乎是一个疯狂的错误,但是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.allOf
或enum
),则通常会导致灾难性的失败。
可悲的是,我重构了代码,这样就不会发生,因此我不再需要提供示例了。我将尝试重现该问题并与您联系。
我在这里看到-Why the Java enum constants initialization is not complete?发生了另一起带有演示的问题。
关于java - JDK 7 SE的Enum.valueOf错误,其中.values()损坏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16307844/