鉴于以下代码,
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public enum SearchDataTypes {
FIELD_DATATYPE_TEXT(String.class,"_t"),
FIELD_DATATYPE_INT(Integer.class,"_i"),
FIELD_DATATYPE_LONG(Long.class,"_l"),
FIELD_DATATYPE_FLOAT(Float.class,"_f"),
FIELD_DATATYPE_DOUBLE(Double.class, "_d" ),
FIELD_DATATYPE_DATE(Date.class,"_dt");
SearchDataTypes(final Class<?> clazz, final String affix) {
this.affix = affix;
this.clazz = clazz;
getAffixMap().put(affix, this);
getClassMap().put(clazz, this);
}
public String getFieldName(String objectFieldName) {
return objectFieldName+affix;
}
public String getObjectFieldName(String FieldName) {
int len = FieldName.length();
len -= this.affix.length();
return FieldName.substring(0, len);
}
public static SearchDataTypes findByAffix(String affix) {
SearchDataTypes obj = getAffixMap().get(affix);
assert obj != null;
return obj;
}
public static SearchDataTypes findByClass(Class<?> clazz) {
SearchDataTypes obj = getClassMap().get(clazz);
assert obj != null;
return obj;
}
private String affix;
private Class<?> clazz;
private static Map<Class<?>, SearchDataTypes> classMap = new HashMap<Class<?>, SearchDataTypes>();
private static Map<String, SearchDataTypes> affixMap = new HashMap<String, SearchDataTypes>();
private static Map<Class<?>, SearchDataTypes> getClassMap() { return classMap; }
private static Map<String, SearchDataTypes> getAffixMap() { return affixMap; }
}
枚举类未实例化(使用枚举抛出NoClassDefFoundError),因为在初始化期间存在NullPointerException。我假设JVM认为map是null。但为什么??
我还能如何为枚举实现查找程序?我不想使用java.util.EnumMap类主要是因为我想更好地理解枚举的内部工作。
谢谢
答案 0 :(得分:4)
将枚举常量视为Java类的公共静态最终成员。与所有静态成员一样,它们按源顺序初始化。因此常量在映射之前被初始化,因此在引用构造函数中的映射时会得到空指针异常,因为映射尚未初始化。
虽然java语法不可能,但简单的解决方案是在枚举之前声明映射 - 但由于这是不可能的,下一个最好的事情是在常量之后初始化静态块中的映射:例如< / p>
public enum SearchDataTypes {
...
FIELD_DATATYPE_DATE(Date.class,"_dt");
private static final Map<String,SearchDataTypes> affixMap = new HashMap<String,SearchDataType>();
private static final Map<Class<?>, SearchDataTypes> classMap = new HashMap<Class<?>, SearchDataTypes>()
static {
for (SearchDataType value : values()) {
map.put(value.affix, value);
map.put(value.clazz, value);
}
}
SearchDataTypes(final Class<?> clazz, final String affix) {
this.affix = affix;
...
}
答案 1 :(得分:2)
实例在枚举的其余部分静态初始化之前构建。如果它们为null,则使用“getters”作为构造它们的映射。
因为它全部发生在枚举类的静态初始化中,所以它本质上是线程安全的 - 你不必使用同步块。