Генерация Перечислений Динамически - PullRequest
12 голосов
/ 12 декабря 2011

Допустим, у меня есть файл с базовым форматом XML, например:

<?xml version="1.0"?>
<enum-set>
    <enum>
        <name>SomeEnum</name>
        <values>
            <value>
                <name>SOMEVALUE</name>
                <displayText>This is some value</displayText>
             </value>
            ... more values ...
        </values>
    </enum>
    ... more enums ...
</enum-set>

, и я хотел превратить SomeEnum во что-то подобное во время выполнения:

public enum SomeEnum implements HasDisplayText {
    SOMEVALUE("This is some value"),
    ... more values ...;

    private String displayText;

    SomeEnum(String displayText) {
        this.displayText = displayText;
    }

    @Override
    public String getDisplayText() {
        return displayText;
    }
}

... а затем передайте недавно созданное перечисление SomeEnum вокруг моего приложения.Как я могу достичь чего-то подобного?Это выполнимо?

Ответы [ 4 ]

17 голосов
/ 12 декабря 2011

То, что вы пытаетесь сделать, не имеет большого смысла. Перечисления действительно используются только во время компиляции, так как они представляют фиксированный набор констант. Во время выполнения, что будет означать динамически генерируемое перечисление - как это будет отличаться от простого объекта? Например:

public class Salutation implements HasDisplayText {

   private String displayText;

   private Salutation(String displayText) {
       this.displayText = displayText;
   }

   @Override
   public String getDisplayText() {
       return displayText;
   }

   public static Collection<Salutation> loadSalutations(String xml) {
      //parse, instantiate, and return Salutations
   }
}

Ваш XML может быть проанализирован во вновь созданных Salutation объектах, которые могут быть сохранены в некоторых Collection или иным образом использоваться вашей программой. Обратите внимание, что в моем примере я ограничил создание Salutation, предоставив ему конструктор private - в этом случае единственный способ получить экземпляры - это вызвать фабричный метод, который принимает ваш XML. Я полагаю, что благодаря этому достигается поведение, которое вы ищете.

8 голосов
/ 12 декабря 2011

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

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

1 голос
/ 26 сентября 2014

Согласен с Оскаром Лопесом. Вот что я сделал, что-то вроде хака.

public static enum Setter {

    DYNAMIC_ENUM_EXAMPLE {

        @Override
        public String setGetValue(String yourValue) {
            return "prefix " + yourValue + " postfix";
        }
    };
    public abstract String setGetValue(String value);
}

Вы можете получить значение следующим образом:

Setter.DYNAMIC_ENUM_EXAMPLE.setGetValue("namaste")

Выход:

prefix namaste postfix
0 голосов
/ 11 апреля 2017

Динамические Перечисления - ответ на Вашу проблему:

public abstract class DEnum<E extends DEnum<E>> implements Comparable<E>, Serializable {

Этот класс имеет сигнатуру, аналогичную стандартному классу Enum. Он имеет защищенный конструктор, позволяющий создавать экземпляры в конкретных классах Enum. Например:

public class YesNo extends DEnum<YesNo> {

    public final static YesNo YES = new YesNo();
    public final static YesNo NO = new YesNo();

Класс DEnum знает имена членов посредством самоанализа:

String name = YesNo.YES.getName();
YesNo yes = YesNo.get(YesNo.class, name);
assert (yes == YesNo.YES);

Существует типизированный метод получения, который извлекает все элементы:

YesNo[] items = yes.getItems();
assert (items.length == 2);

Позволяет динамически добавлять элементы во время выполнения с помощью (из базы данных или из файла):

YesNo maybe = getOrCreateIfNotExists(YesNo.class, "MAYBE");
items = yes.getItems();
assert (items.length == 3);

Которые ведут себя так же, как статические члены:

YesNo unknown = YesNo.get(YesNo.class, "MAYBE");
assert (unknown == maybe);
...