Dynamic Enums in Java
Olivier Van de Velde
Technical Authority and Scrum Master EBP Web Apps at Siemens Mobility
The Enum was introduced in Java 1.5. By definition its members are static and no members can be added at run time. Sometimes it is very convenient to store the items or to store additional items in a DB or on file. This is where the dynamic enum (DEnum) comes into play.
The DEnum class has a signature similar to the standard Enum class:
public abstract class DEnum<E extends DEnum<E>> implements Comparable<E>, Serializable {
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:
// when not set the name is lazily computed by introspection
protected String name = null;
public String getName() {
if (name == null) {
Class<?> clazz = getClass();
// Scan the static enumeration values defined in the enumeration
// class to compute name
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
Object object = field.get(this);
if (this == object) {
name = field.getName();
break;
}
} catch (IllegalArgumentException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
} catch (IllegalAccessException ex) {
// normal behaviour, this property is private, so skip it
logger.fine("field " + field.getName() + " is private : " + ex.getMessage());
}
}
if (name == null) {
throw new IllegalArgumentException("Can't find name for enum");
}
}
return name;
}
Usage is as follows:
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);
Financial Advisor | Helping Your Retirement Dreams become Reality! | Helping IT Professionals and Business Owners Optimizing Tax Strategies | Helping Saving for Education for Kids | Estate Planning Considerations
6 年you can reply here or send me email at [email protected]. Thank you.
Financial Advisor | Helping Your Retirement Dreams become Reality! | Helping IT Professionals and Business Owners Optimizing Tax Strategies | Helping Saving for Education for Kids | Estate Planning Considerations
6 年Hi, The solution you proposed seems very elegant. However I have few questions (1). So is DEnum user defined class or is it introduced in Java API in new version. (2) Currently we are using enum class with constant list however now we want to add elements programmatically, With your solution, do we have to replace enum class with regular class?? (3) The method "getOrCreateIfNotExists" has to be implemented by user (as I don't see the implementation here. Correct? (4) Any limitations with this solution?