2011-12-11 3 views
12

Скажем, у меня есть файл, формат которого является основной 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; 
    } 
} 

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

ответ

14

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

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. Я считаю, что это приводит к поведению, которое вы ищете.

+0

Имеет смысл. Я спросил о перечислениях специально, потому что в моей иерархии сейчас слишком много (не абсурдная сумма, а всего несколько), и я надеялся их устранить. –

+0

@ Chris - Подождите, так ваш вопрос о генерации кода или создании их во время выполнения? –

+0

На самом деле речь идет о создании их во время выполнения. Полагаю, это другое дело. –

6

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

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

0

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

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

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

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

Этот класс подпись, аналогичная стандарту Enu m класс. Он имеет защищенный конструктор, позволяющий создавать экземпляры в конкретных классах 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); 
+0

Вы должны включить ссылку на реализацию 'DEnum' или опубликовать ее здесь –

Смежные вопросы