简体   繁体   English

Java 1.5枚举:为什么不能对1.5枚举使用'findBy'?

[英]Java 1.5 Enum: Why can't I use 'findBy' with 1.5 enums?

Given the code below, 鉴于以下代码,

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; }


}

The enum class is not getting instantiated (using the enum throws NoClassDefFoundError) because the there is NullPointerException during initialization. 枚举类未实例化(使用枚举引发NoClassDefFoundError),因为初始化期间存在NullPointerException。 I assume that the JVM is thinking either map is null. 我假设JVM认为任一映射都为null。 But why?? 但为什么??

How else can I implement a finder for enums? 我还能如何实现枚举的查找器? I prefer not to use java.util.EnumMap class mainly because I want to better understand the innerworking of enums. 我宁愿不使用java.util.EnumMap类,主要是因为我想更好地理解枚举的内部工作。

thank you 谢谢

Think of the enum constants as public static final members of the Java class. 将枚举常量视为Java类的公共静态最终成员。 Like all static members, they are initialized in source order. 像所有静态成员一样,它们按源顺序初始化。 So the constants are being initialized before the maps, thus you'll get the null pointer exception when referencing the map in the constructors, because the map hasn't been initialized yet. 因此,常量是在映射之前初始化的,因此在构造函数中引用映射时,您将获得null指针异常,因为映射尚未初始化。

Though not possible with java syntax, the simple solution would be to declare the maps before the enums--but since that's not possible, the next best thing is to just initialize the maps in a static block after the constants: eg 尽管使用Java语法无法实现,但简单的解决方案是在枚举之前声明映射-但这是不可能的,因此,下一个最好的事情就是在常量之后的静态块中初始化映射:例如

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;
    ...
}

The instances are getting constructed before the static initialization of the rest of the enum. 在静态枚举其余枚举之前构造实例。 Use "getters" for the maps that will construct them if they are null. 如果地图为null,则使用“ getter”构建地图。

Because it's all happening within static initialization of the enum class, it's intrinsically thread-safe - you don't have to use a synchronize block. 因为这都是在enum类的静态初始化内发生的,所以它本质上是线程安全的-您不必使用syncyize块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM