Я могу добавлять и удалять элементы перечисления во время выполнения в Java
можно добавлять и удалять элементы из перечисления в Java во время выполнения?
например, могу ли я прочитать в метках и аргументах конструктора перечисления из файла?
@saua, это просто вопрос о том, можно ли это сделать из интереса на самом деле. Я надеялся, что будет какой-то аккуратный способ изменить запущенный байт-код, возможно, используя BCEL или что-то. Я также следил за этим вопросом, потому что я понял, что не был полностью уверен когда перечисление должно быть использовано.
Я довольно убежден, что правильным ответом было бы использовать коллекцию, которая обеспечивала бы уникальность вместо перечисления, если я хочу иметь возможность безопасно изменять содержимое во время выполнения.
6 ответов:
нет, перечисления должны быть полным статическим перечислением.
во время компиляции вы можете создать свое перечисление .java-файл из другого исходного файла какого-то рода. Вы могли бы даже создать .файл класса, как это.
в некоторых случаях может потребоваться набор стандартных значений, но разрешить расширение. Обычный способ сделать это-иметь
interface
для интерфейса иenum
что реализуетinterface
для стандартных значений. Конечно, вы теряете способностьswitch
когда у вас есть только ссылка наinterface
.
за занавесом перечисления являются POJOs с частным конструктором и кучей публичных статических конечных значений типа перечисления (см. здесь для примера). В самом деле, до тех пор, пока с java5, это считалось наилучшей практики, чтобы построить свой собственный перечисления таким образом, и с java5 представил
enum
ключевое слово в стенографии. Смотрите источник для Перечислениечтобы узнать больше. поэтому не должно быть никаких проблем, чтобы написать свой собственный "TypeSafeEnum" с публичным статическим финалом массив констант, которые считываются конструктором или передаются ему.
кроме того, сделайте себе одолжение и переопределить
equals
,hashCode
иtoString
и если возможно создатьvalues
методвопрос в том, как использовать такое динамическое перечисление... вы не можете прочитать значение "PI=3.14" из файла для создания
enum MathConstants
а затем идти вперед и использоватьMathConstants.PI
везде, где вы хотите...
Мне нужно было сделать что-то вроде этого (для целей модульного тестирования), и я наткнулся на это-EnumBuster: http://www.javaspecialists.eu/archive/Issue161.html
позволяет добавлять, удалять и восстанавливать значения перечислений.
Edit: Я только начал использовать это, и обнаружил, что есть некоторые небольшие изменения, необходимые для java 1.5, которые я в настоящее время застрял с:
- добавить массив copyOf статические вспомогательные методы (например, возьмите эти версии 1.6:http://www.docjar.com/html/api/java/util/Arrays.java.html)
- Изменить EnumBuster.undoStack в стек
<Memento>
- в undo () измените undoStack.опрос () для отмены стека.isEmpty ()? null: undoStack.pop ();
- строка VALUES_FIELD должна быть "ENUM$VALUES" для перечислений java 1.5, которые я пробовал до сих пор
я столкнулся с этой проблемой на формирующий проект моей молодой карьеры.
подход, который я принял, состоял в том, чтобы сохранить значения и имена перечисления извне, а конечной целью было написать код, который выглядел как можно ближе к перечислению языка.
Я хотел, чтобы мое решение выглядело так:
enum HatType { BASEBALL, BRIMLESS, INDIANA_JONES } HatType mine = HatType.BASEBALL; // prints "BASEBALL" System.out.println(mine.toString()); // prints true System.out.println(mine.equals(HatType.BASEBALL));
и я закончил с чем-то вроде этого:
// in a file somewhere: // 1 --> BASEBALL // 2 --> BRIMLESS // 3 --> INDIANA_JONES HatDynamicEnum hats = HatEnumRepository.retrieve(); HatEnumValue mine = hats.valueOf("BASEBALL"); // prints "BASEBALL" System.out.println(mine.toString()); // prints true System.out.println(mine.equals(hats.valueOf("BASEBALL"));
Так как мои требования были, что это должно было быть можно добавить членов в перечисление во время выполнения, я также реализовал эту функциональность:
hats.addEnum("BATTING_PRACTICE"); HatEnumRepository.storeEnum(hats); hats = HatEnumRepository.retrieve(); HatEnumValue justArrived = hats.valueOf("BATTING_PRACTICE"); // file now reads: // 1 --> BASEBALL // 2 --> BRIMLESS // 3 --> INDIANA_JONES // 4 --> BATTING_PRACTICE
я назвал его динамическим перечислением "pattern", и вы читали о оригинальный дизайн и ее пересмотренное издание.
разница между ними заключается в том, что пересмотренное издание было разработано после того, как я действительно начал grok OO и DDD. Первый, который я разработал, когда я все еще писал номинально процедурный DDD, под давлением времени нет меньше.
вы можете загрузить класс Java из исходного кода во время выполнения. (Используя JCI, BeanShell или JavaCompiler)
Это позволит вам изменить значения перечисления, как вы хотите.
Примечание: это не изменит никаких классов, которые ссылаются на эти перечисления, поэтому это может быть не очень полезно в реальности.