Java 1.5 Enum: Почему я не могу использовать 'findBy' с 1,5 перечислениями? - PullRequest
0 голосов
/ 30 сентября 2011

Учитывая приведенный ниже код,

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


}

Класс enum не создается (с использованием метода enum throws NoClassDefFoundError), поскольку во время инициализации существует исключение NullPointerException.Я предполагаю, что JVM думает, что любая карта является нулевой.Но почему ??

Как еще можно реализовать поиск для перечислений?Я предпочитаю не использовать класс java.util.EnumMap главным образом потому, что хочу лучше понять внутреннюю работу перечислений.

спасибо

Ответы [ 2 ]

4 голосов
/ 30 сентября 2011

Думайте о константах перечисления как об открытых статических конечных членах класса Java. Как и все статические члены, они инициализируются в исходном порядке. Таким образом, константы инициализируются перед картами, поэтому вы получите исключение нулевого указателя при ссылке на карту в конструкторах, потому что карта еще не была инициализирована.

Хотя это невозможно с помощью синтаксиса 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;
    ...
}
2 голосов
/ 30 сентября 2011

Экземпляры создаются перед статической инициализацией остальной части перечисления.Используйте «добытчики» для карт, которые будут строить их, если они нулевые.

Поскольку все это происходит во время статической инициализации класса enum, он по своей сути поточно-ориентирован - вам не нужно использовать блок синхронизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...