问题的起因
起因来自于我对于java枚举类的无知。
我本来想定义这样一个枚举类:
public enum MenuOptions {
CHAT_ROOM("#1"),
MENU("#0"),
ERROR("#9999");
private String value;
MenuOptions(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
// 根据字符串的值返回枚举常量
public static MenuOptions valueOf(String value) {
//...
return MenuOptions.ERROR;
}
}
关键是定义的这个方法:
我用的IDE是IDEA,jdk版本是1.8,但是编译版本、语言级别是1.7
这里报方法定义已存在,,,???
这个时候,想起来枚举类有一个valueOf方法的,传入的参数是枚举常量的变量名,返回这个枚举常量,然后debug,发现枚举类内部调用了java.lang.Enum类的这个方法:
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);
}
猜测、分析
猜测可能是编译的时候,这个类被JDK默认继承了Enum类,通过IDEA查看class反编译文件:
what???什么也没有。。。
使用javap来看这个class文件:
首先,确实可以看到这个类继承自Enum类,然后这个类valueOf(String)调用了Enum.valueOf(Class,String)方法:
but,这个类的valueOf(String)在Enum类里没有找到(下面是Enum类的所有方法声明):
这样看来是JDK编译的时候,动态增加的,不知道猜想是否准确,回头找个时间好好查下资料了解下。
最终解决方案
碰见这样的,我也不知道怎么解决了,本来我这个方法,是想通过传入的值返回相应的枚举值,不是像默认的那样传入枚举量的变量名字符串。
那这样的话,我只能换个名了,,,尴尬。。。如下完整代码 :
public enum MenuOptions {
CHAT_ROOM("#1"),
MENU("#0"),
ERROR("#9999"){
{
innerMap.put("#1", "CHAT_ROOM");
innerMap.put("#0", "MENU");
innerMap.put("#9999", "ERROR");
}
};
private String value;
protected Map<String, String> innerMap = new HashMap<>();
MenuOptions(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
// 根据字符串的值返回枚举常量
public static MenuOptions valueOf2(String value) {
String name = MenuOptions.ERROR.innerMap.get(value.trim().intern());
if (name == null) {
return MenuOptions.ERROR;
}
MenuOptions option = valueOf(name);
return option;
}
}