Creating Enum's Dynamically



import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Constructor;
/**
* Java doesn't allow creation of enum dynamically through reflection. It will
* throw "Cannot reflectively create enum objects".
*
* This code will creates enum by skipping the exception.
*
* Note: Tested this code Oracle JDK
*
*
* @note Use this when you need to return a default value for a specified enum,
* which is not in your ENUM list. If your enum is auto generated and
* cannot modify or use a defined value as default, you can use
* EnumCreator.
*
*/
public class EnumCreator {
public static <T extends Enum<?>> T createEnum(String enumString,
Class<T> enumType, Object... params) {
if (!Enum.class.isAssignableFrom(enumType)) {
throw new RuntimeException("class " + enumType
+ " is not an instance of Enum");
}
T constructObj = null;
try {
Constructor<?> con = enumType.getDeclaredConstructors()[0];
Method[] methods = con.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getName().equals("acquireConstructorAccessor")) {
m.setAccessible(true);
m.invoke(con, new Object[0]);
}
}
Field[] fields = con.getClass().getDeclaredFields();
Object ca = null;
for (Field f : fields) {
if (f.getName().equals("constructorAccessor")) {
f.setAccessible(true);
ca = f.get(con);
}
}
if (ca != null) {
Object[] enums = Object[].class.cast(enumType.getMethod(
"values").invoke(null));
Method m = ca.getClass().getMethod("newInstance",
new Class[] { Object[].class });
m.setAccessible(true);
Object[] args = new Object[2 + params.length];
args[0] = enumString; // name
args[1] = enums.length; // Ordinal
int argslen = 2;
for (Object param : params) {
args[argslen++] = param;
}
constructObj = enumType.cast(m
.invoke(ca, new Object[] { args }));
}
} catch (Throwable e) {
e.printStackTrace();
}
return constructObj;
}
}