Generating Enums Dynamically

Actually it is possible to create enum instances dynamically, but it's a total hack, I wouldn't advise it at all - maybe you're misunderstanding the nature of an enum, it's a compile-time feature of the language, and you're not supposed to add/remove instances from it at runtime.

Anyway, if you're interested in the hack for creating enum instances dynamically, take a look at this article.


What you're trying to do doesn't make a whole lot of sense. Enums are really only for the benefit of compile time, as they represent a fixed set of constants. At runtime, what would be the meaning of a dynamically generated enum - how would this be different from an plain object? For example:

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
   }
}

Your XML could be parsed into newly instantiated Salutation objects, which could be stored in some Collection or otherwise used by your program. Notice in my example, I've restricted the creation of Salutation by giving it a private constructor - in this case the only way to retrieve instances is by calling the factory method which takes your XML. I believe this achieves the behavior you're looking for.


Dynamic Enums is the answer to your problem:

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

This class has a signature similar to the standard Enum class. It has a protected constructor to allow instance creation in concrete Enum classes. For example:

public class YesNo extends DEnum<YesNo> {

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

The DEnum class knows the names of the members by introspection:

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

There is a typed getter that retrieves all the items:

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

It allows to add members dynamically at run time with (from database or from file):

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

Which have the same behavior as the static members:

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