Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Java создать enum из файла

338  
natuerlich blond свой человек18.10.14 00:56
natuerlich blond
NEW 18.10.14 00:56 
Что-то Гугл мне не помог.
Задача следующая. Вычитать из файла поля для enum.
Например, запись в файле: field1, field2, field3
На основе этих записей хотелось бы создать enum следующего вида.
enum Fields {field1, field2, field3;}
xml или properties-файл тоже подойдут. Буду благодарна за подсказку.
#1 
kashej местный житель18.10.14 08:25
kashej
NEW 18.10.14 08:25 
в ответ natuerlich blond 18.10.14 00:56
Вот тут вроде как создают enumы "на лету": http://www.javaspecialists.eu/archive/Issue161.html с помощью reflection.
Есть еще и много других статей. Погуглите "create enum" dynamically java или "create enum" at runtime java
Я ознакомился с ними бегло лишь ради интереса, т.к. сам такого никогда не делал, да и особого смысла в этом не вижу. Но Вам решать.
http://denis-aristov.ucoz.com
#2 
Murr патриот18.10.14 09:57
Murr
NEW 18.10.14 09:57 
в ответ natuerlich blond 18.10.14 00:56
А есть какая-то сложность записать в другой файл
<
Stream sw;
sw.Write("enum Fields {");
sw.Write(fields);
sw.Write("};")
>
и откомпилировать?
Другое дело - созадавать один <enum> - занятие бессмысленное, а создавать что-то более обьемное - бессмысленно таким методом.
#3 
MrSanders старожил18.10.14 12:32
NEW 18.10.14 12:32 
в ответ natuerlich blond 18.10.14 00:56
В ответ на:
На основе этих записей хотелось бы создать enum следующего вида.
enum Fields {field1, field2, field3;}

Вам нужно генерировать код, который потом будет использоваться в проекте, или вам надо в работающей виртуальной машине динамически создавать enum?
1. Генерация.
У вас есть источник (файл, БД, веб), вы получаете из него имя enum-а и список его полей и генерируете .java файл с кодом enum-а.
Потом этот enum используется программистами в их коде.
2. Динамическое создание. (runtime)
Ваша программа работает в JVM, получает (или забирает сама) из какого-то источника информацию об enum-е, который надо сгенерировать и создает новый класс не прерывая работу приложения.
#4 
natuerlich blond свой человек18.10.14 20:52
natuerlich blond
NEW 18.10.14 20:52 
в ответ MrSanders 18.10.14 12:32
н.п.
Наверное, нужно действительно объяснить поподробнее, для чего мне это нужно.
Имеются таблицы, допустим из ДБ, с определенными полями. Имена этих полей я перечисляю в enum и использую структуру Map для объекта, которые представляет строку.
Для определенных полей должна быть проведена валидация, причем по очень разным правилам, они могут касаться и одной строки, и проверки по всей таблицы, или сверки разных таблиц.
Сейчас я дефинирую поля на проверку например в классе каждого конкретного правила. Просто инициализирую Array со значениями из enum.
Недостаток этого решения: если на проверку по какому-то правилу нужно добавить в Array еще одно поле, или например, изменить кол-во полей в таблице, то нужно перекомпилировать класс. Вот этого я хочу избежать.
Поэтому я хотела бы при старте приложения вычитывать названия полей enum из файла. При этом enum должен создаваться один раз при старте, потом в него ничего не добавляется.
Конечно, можно вместо enum использовать лист, но мне хотелось бы все же с enum попробовать.
@kashej, ваша ссылка не открывается.
#5 
Murr патриот19.10.14 00:19
Murr
NEW 19.10.14 00:19 
в ответ natuerlich blond 18.10.14 20:52
если на проверку по какому-то правилу нужно добавить в Арраы еще одно поле
-----
Замени Array на Hashtable - все пойдет в динамике...
#6 
kashej местный житель19.10.14 07:15
kashej
NEW 19.10.14 07:15 
в ответ natuerlich blond 18.10.14 20:52, Последний раз изменено 19.10.14 07:16 (kashej)
Да, что-то она плохо открывалась, но теперь вроде работает. Но вот по-моему даже лучше статейка: niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamicall...
Там описано, как добавлять динамически новые значения к еnumу.
http://denis-aristov.ucoz.com
#7 
natuerlich blond свой человек19.10.14 13:13
natuerlich blond
NEW 19.10.14 13:13 
в ответ kashej 19.10.14 07:15
Ясно, спасибо большое. Надеялась, что проще есть решение.
Наверное, лучше заменить листом или другой структурой.
#8 
MrSanders старожил19.10.14 14:32
NEW 19.10.14 14:32 
в ответ natuerlich blond 19.10.14 13:13
В ответ на:
Надеялась, что проще есть решение.

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

Адназначна. Пр инициализации читаем какую-нибудь конфигурация и создаем список, мэп (что удобнее в доступе).
Я сильно удивился зачем могло понадобилось в рантайме создавать enum. Ни в обной статье где пишут про то что это можно сделать и как именно это делать не пишут - а зачем.
Генерировать код enum-а из, например, схемы БД - нормальное решение, такое может пригодиться (см. DRY).
enum нужен для двух вещей:
- жестко ограничить количество вариантов, например для использования в switch-е, или чтобы не дать программистам, использующим вашу библиотеку, передавать методам неподдерживаемое значение - просто ограничиваем допустимые значения параметра, вводим enum.
- для гарантированной "ленивой" инициализации полей при обращении к ним (не ломая голову над мультипоточным доступом).
#9 
natuerlich blond свой человек19.10.14 14:55
natuerlich blond
NEW 19.10.14 14:55 
в ответ MrSanders 19.10.14 14:32
Мне хотелось использовать enum в этой задаче, потому что для меня названия полей - это список констант. И с использованием enum я гарантирую то, что не будет ошибок в передаче запросов с именем поля, к примеру.
Но в фирме принципиально избегают декларацию каких-либо названий в коде, поскольку перекомпилировать никому не хочется, Поэтому моя задача сейчас именно изменить загрузку названий полей. Ну ниче, раз с enum не получилось, есть и другие решения, хотя первый вариант мне больше нравился.
#10 
Murr патриот19.10.14 15:45
Murr
NEW 19.10.14 15:45 
в ответ natuerlich blond 19.10.14 13:13
Надеялась, что проще есть решение.
-----
Так выше Я тебе уже сказал где оно...
Наверное, лучше заменить листом или другой структурой.
-----
Тебе требуется сопоставить некоему объекту набор валидаторов.
Прямой путь сделать это - Hashtable<objID, List<IValidator>>
Определяй singleton или static и заполняй его как угодно...
#11 
Murr патриот19.10.14 15:53
Murr
NEW 19.10.14 15:53 
в ответ natuerlich blond 19.10.14 14:55
поскольку перекомпилировать никому не хочется
-----
Перекомпилировать - это пустяки. Реальная проблема - отслеживать изменения... особливо - в мультиверсионке...
с использованием enum я гарантирую то, что не будет ошибок в передаче запросов с именем поля
-----
А оно надо?
Не проще ли исключить "передачу запросов с именем поля"?
Например, передавать само поле... или таблицу... имя то из них всегда можно получить...
#12 
natuerlich blond свой человек19.10.14 16:51
natuerlich blond
NEW 19.10.14 16:51 
в ответ Murr 19.10.14 15:45
В ответ на:
Тебе требуется сопоставить некоему объекту набор валидаторов.
Прямой путь сделать это - Hashtable<objID, List<IValidator>>
Определяй singleton или static и заполняй его как угодно...

А, теперь поняла, что ты имел ввиду. Это конечно тоже вариант, только у меня структура несколько другая. У меня наоборот каждое правило содержит список полей, которые валидируются. По-моему, так проще по таблице итерировать: валидировать сразу всю строку. Ну да неважно, в принципе смысл понятен. Enum отправляем в корзину.
#13 
Murr патриот19.10.14 18:08
Murr
NEW 19.10.14 18:08 
в ответ natuerlich blond 19.10.14 16:51
У меня наоборот каждое правило содержит список полей, которые валидируются.
По-моему, так проще по таблице итерировать: валидировать сразу всю строку.
-----
Плохая архитектура.
Правило должно уметь провалидировать поле (если это валидация поля) или таблицу... или еще что-то, для чего оно предназначено.
Ни хранить какой-то список, ни, тем более, получать доступ к валидируемому элементу - не должно даже и думать...
Плюс - навигация по элементам - отдельно, выборка валидаторов - отдельно... тогда появится возможность что-то управляемо изменять...
Если хочешь помаятся - подумай над следующим:
- две и более таблицы содержат одинаковые поля, но требуют разных валидаций...
- имя поля совпадает с именем таблицы...
#14 
  digital.pilot патриот19.10.14 23:08
digital.pilot
NEW 19.10.14 23:08 
в ответ MrSanders 19.10.14 14:32
В ответ на:
enum нужен для двух вещей:

я бы добавил еще "для строгой типизации логически различающихся данных" и "для предотвращения волшебных чисел"
#15 
MrSanders старожил20.10.14 13:06
NEW 20.10.14 13:06 
в ответ digital.pilot 19.10.14 23:08
Про волшебные числа я начал писать, но понял что я таким макаром доклад на два листа выдам, да и вроде как и не спрашивали про то где enum вообще нужен, и сжал до "- жестко ограничить количество вариантов"
#16 
natuerlich blond свой человек21.10.14 22:01
natuerlich blond
NEW 21.10.14 22:01 
в ответ Murr 19.10.14 18:08
В ответ на:
Если хочешь помаятся - подумай над следующим:
- две и более таблицы содержат одинаковые поля, но требуют разных валидаций...
- имя поля совпадает с именем таблицы...

Таблицы с полями у меня никак не перекликаются, даже если названия одинаковые. А вот пункт 1 - это да, надо переработать, спасибо.
#17 
Murr патриот22.10.14 09:42
Murr
NEW 22.10.14 09:42 
в ответ natuerlich blond 21.10.14 22:01
никак не перекликаются
-----
Никик не пересекаются означает, что информация (или):
1. уникальна в пределах системы
2. доступна только через строго типизированный обьект
3. имеет дополнительные свойства, позволяющие считать ее уникальной
У тебя НЕ выполняются эти условия...
#18 
natuerlich blond свой человек23.10.14 19:03
natuerlich blond
NEW 23.10.14 19:03 
в ответ Murr 22.10.14 09:42
2. доступна только через строго типизированный обьект
У тебя НЕ выполняются эти условия...
с чего ты взял?
#19 
Murr патриот23.10.14 19:24
Murr
23.10.14 19:24 
в ответ natuerlich blond 23.10.14 19:03
с чего ты взял?
------
С <enum>а...
#20