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