2011-02-03 84 views
14

Necesito crear una enumeración basada en una tabla de la base de datos.¿Cómo crear enum dinámicamente?

DB MyColors mesa: Identificación/título/valor 1/rojo/1 2/Verde/4

dinámico crear

enum MyColors { 
    Red=1, 
    Green=4; 
} 
+5

Esa es una pregunta algo contradictoria. Los mensajes se usan generalmente para instancias que usted sabe que existen antes del tiempo de ejecución. Sin embargo, entiendo tu situación. He preguntado algo en una línea similar: http://stackoverflow.com/questions/492096/persisting-data-suited-for-enums –

+0

¿qué estás tratando de hacer exactamente? - Si intenta reemplazar 1 con rojo, 4 con verde en su resultado sql, puede hacer una combinación para mostrar el nombre correspondiente –

+0

Lo que desea crear no compila, '1' no se puede asignar a' MyColors .Red' – meriton

Respuesta

11

Puede crear dinámicamente código fuente mediante la lectura de la base de datos y simplemente dando salida a los resultados en un formato propicio para construir una enumeración. Sin embargo, no es práctico crear una enumeración en tiempo de ejecución. Estarías mejor con algún tipo de matriz asociativa.

1

No está claro si desea generar código fuente o no. Supongo que no, ya que incluso compilado sin código en el mismo programa podría acceder a los objetos enum, excepto a través de la reflexión.

¿Por qué no asociar la tabla a un objeto ColorEntity utilizando JPA? A continuación, puede tener una lista o un mapa de estas entidades o lo que necesite.

2

Una opción es definir un Esquema XML y los valores requeridos como enum y generar los archivos de clase, para que podamos gestionar los valores fuera del código fuente, sin embargo no podemos generar dinámicamente los valores enum de la base de datos.

2

En realidad hay una posibilidad de crear dinámicamente las enumeraciones que utilizan la reflexión: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically

+1

Me gusta esa idea. Tengo el mismo problema. Una enumeración utilizada en todas partes en un proyecto muy grande que de repente deseamos que se base en una base de datos ... Refactorizar todo ese código me hace estremecer, mientras que construir dinámicamente una enumeración suena como si fueran órdenes de magnitud más simples. –

1
/** 
    * Add an enum instance to the enum class given as argument 
    * 
    * @param the type of the enum (implicit) 
    * @param enumType the class of the enum to be modified 
    * @param enumName the name of the new enum instance to be added to the class. 
    */ 
    @SuppressWarnings("unchecked") 
    public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName) { 

     // 0. Sanity checks 
     if (!Enum.class.isAssignableFrom(enumType)) { 
      throw new RuntimeException("class " + enumType + " is not an instance of Enum"); 
     } 
     // 1. Lookup "$VALUES" holder in enum class and get previous enum instances 
     Field valuesField = null; 
     Field[] fields = enumType.getDeclaredFields(); 
     for (Field field : fields) { 
      if (field.getName().contains("$VALUES")) { 
       valuesField = field; 
       break; 
      } 
     } 
     AccessibleObject.setAccessible(new Field[] { valuesField }, true); 

     try { 

      // 2. Copy it 
      T[] previousValues = (T[]) valuesField.get(enumType); 
      List values = new ArrayList(Arrays.asList(previousValues)); 

      // 3. build new enum 
      T newValue = (T) makeEnum(enumType, // The target enum class 
        enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED 
        values.size(), 
        new Class<><[] {}, // can be used to pass values to the enum constuctor 
        new Object[] {}); // can be used to pass values to the enum constuctor 

      // 4. add new value 
      values.add(newValue); 

      // 5. Set new values field 
      setFailsafeFieldValue(valuesField, null, 
        values.toArray((T[]) Array.newInstance(enumType, 0))); 

      // 6. Clean enum cache 
      cleanEnumCache(enumType); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new RuntimeException(e.getMessage(), e); 
     } 
    } 

El código anterior podría ayudarle.