Объявите перечисление java с массивом String - PullRequest
2 голосов
/ 07 июня 2010

Я пытаюсь объявить тип enum на основе данных, которые я извлекаю из базы данных. У меня есть метод, который возвращает массив строк всех строк в таблице, которые я хочу преобразовать в перечислимый тип. Есть ли способ построить перечисление с массивом?

Это то, что я пытался, но из того, как это выглядело в затмении, казалось, что он только что создал метод с таким именем:

public enum ConditionCodes{
    Condition.getDescriptions();
}

Заранее спасибо!

Ответы [ 7 ]

12 голосов
/ 07 июня 2010

Вы не можете.

Значения enum должны быть известны во время компиляции .Если у вас есть что-то еще, то это не enum.

. Вы можете довольно близко подойти к реализации, похожей на старые типизированные перечисления , которые использовались до того, как в языке Java появилась поддержкадля этой техники с помощью ключевого слова enum.Вы можете использовать эти методы, но просто замените поля static final значениями, считанными из БД.

3 голосов
/ 07 июня 2010

Чтобы ваше перечисление было полезным, оно должно быть записано во время компиляции.Генерация перечисления из запроса к базе данных подразумевает, что вы ожидаете увидеть новые значения перечисления во время выполнения.Даже если вы создали генератор кода для создания вашего перечислимого класса на лету с помощью запроса к базе данных, вы не сможете ссылаться на эти значения перечисления в своем коде, что является смыслом их наличия.

1 голос
/ 07 июня 2010

Трудно понять, как любой компилятор может это поддерживать.

Предполагается, что весь смысл перечисления в том, что вы получаете проверку правильности ваших значений во время компиляции. Скажем, если вы объявляете enum «enum MyStatusCode {FOO, BAR, PLUGH}», то в вашем коде, если вы пишете «MyStatusCode.FOO», все хорошо, но если вы пишете «MyStatusCode.ZORK», вы получаете ошибка времени Это защищает вас от неверного написания значений или путаницы в значениях одного перечисления по сравнению с другим. (У меня только недавно возникла проблема, когда программист случайно назначил метод доставки для типа транзакции, таким образом, волшебным образом превратив продажу в корректировку запасов, когда он намеревался изменить доставку на дом на самовывоз.)

Но если ваши значения определяются динамически во время выполнения, как может компилятор сделать это? Если вы написали MyStatusCode.ZORK в приведенном выше примере, компилятор не сможет узнать, будет ли это значение в базе данных во время выполнения или нет. Даже если вы представляете компилятор достаточно умным, чтобы выяснить, как заполняется перечисление, и проверить базу данных, чтобы увидеть, присутствует ли это значение в соответствующей таблице СЕЙЧАС, он не сможет узнать, будет ли он там, когда вы на самом деле запустите .

Короче говоря, то, что вы хотите, сильно отличается от перечисления.

0 голосов
/ 07 июня 2010

Больше, чем ты не можешь, ты не хочешь. Каждое перечисление, даже довольно классное перечисление в Java, ориентировано на код.

Это в точности то же самое, что и коллекция, но с помощью enum вы, как правило, пишете дублированный код всякий раз, когда сталкиваетесь с ним - с коллекцией вы, скорее всего, будете писать цикл.

Я предлагаю вам создать класс с закрытым конструктором и попросить его создать экземпляры самого себя, а затем предоставить getInstance (String) для извлечения экземпляра. Это похоже на старый тип безопасности enum.

В долгосрочной перспективе, однако, будет лучше, если вам удастся получить достаточное количество интеллекта для этого класса, где вы никогда не будете дифференцироваться в конкретном экземпляре - переходя от способа Enum сделать это:

if(myEnum.stringValue.equals("EnumTarget"))
    executeCode();

ОО способ сделать это:

myEnumLikeObject.executeCode();

Перемещение желаемого кода в «enum» - предпочтительно делегирование непосредственно в содержащийся объект, который создается и устанавливается в «enum» во время создания.

0 голосов
/ 07 июня 2010

Я думаю, что здесь вам понадобится список или набор вместе с некоторыми служебными методами для поиска и сравнения.

Итак, вот ваш список

List<String> conditionCodes = new ArrayList<String>();
//Somehow get Rows or POJO Beans from database with your favorite framework
Collection<Row> dbRows = getConditionCodes();
for(Row curRow : dbRows)
     conditionCodes.add(curRow.getName());

И для поиска

public boolean conditionExists(String name) {
    return conditonCodes.contains(name);
}

public String getCondition(String name) {
    return conditionCodes.get(name);
}

(конечно, вы, возможно, захотите использовать собственные методы List вместо создания своих собственных)

0 голосов
/ 07 июня 2010

Если вы хотите по-настоящему сойти с ума, я думаю обработка аннотаций может сделать это.Обработка аннотаций позволяет вам перехватить компилятор и заставить его волшебным образом изменять вещи при наличии @annotation.

Естественно, значения в перечислении будут теми, которые были доступны во время компиляции.

0 голосов
/ 07 июня 2010

Нет, это невозможно, потому что тип enum должен быть определен во время компиляции, и вам нужно его динамически создать.

Возможно, вам будет лучше, если вместо этого использовать класс.

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