una - ¿Puedo agregar y eliminar elementos de enumeración en tiempo de ejecución en Java?
enum java netbeans (6)
Detrás de la cortina, las enumeraciones son POJO con un constructor privado y un grupo de valores finales estáticos públicos del tipo de enumeración (consulte here para ver un ejemplo). De hecho, hasta Java5, se consideró una mejor práctica construir tu propia enumeración de esta manera, y Java5 introdujo la palabra clave enum
como una abreviatura. Consulte la fuente de Enum<T> para obtener más información.
Por lo tanto, no debería ser un problema escribir su propio ''TypeSafeEnum'' con una matriz final pública estática de constantes, que el constructor lea o le pase.
Además, hazte un favor y anula equals
, hashCode
y toString
, y si es posible crea un método de values
La pregunta es cómo usar una enumeración tan dinámica ... no se puede leer el valor "PI = 3.14" de un archivo para crear enum MathConstants
y luego continuar y usar MathConstants.PI
donde quieras ...
¿Es posible agregar y eliminar elementos de una enumeración en Java en tiempo de ejecución?
Por ejemplo, ¿podría leer las etiquetas y los argumentos del constructor de una enumeración de un archivo?
@saua, es solo cuestión de si realmente se puede hacer sin interés. Esperaba que hubiera alguna manera ordenada de alterar el bytecode en ejecución, tal vez usando BCEL o algo así. También he seguido con esta pregunta porque me di cuenta de que no estaba totalmente seguro de cuándo debería usarse una enumeración.
Estoy bastante convencido de que la respuesta correcta sería utilizar una colección que asegure la unicidad en lugar de una enumeración si quiero poder alterar los contenidos de forma segura en el tiempo de ejecución.
Enfrenté este problema en el proyecto formativo de mi joven carrera .
El enfoque que tomé fue guardar los valores y los nombres de la enumeración externamente, y el objetivo final era poder escribir código que se pareciera lo más posible a un enum de lenguaje.
Quería que mi solución se viera así:
enum HatType
{
BASEBALL,
BRIMLESS,
INDIANA_JONES
}
HatType mine = HatType.BASEBALL;
// prints "BASEBALL"
System.out.println(mine.toString());
// prints true
System.out.println(mine.equals(HatType.BASEBALL));
Y terminé con algo como esto:
// in a file somewhere:
// 1 --> BASEBALL
// 2 --> BRIMLESS
// 3 --> INDIANA_JONES
HatDynamicEnum hats = HatEnumRepository.retrieve();
HatEnumValue mine = hats.valueOf("BASEBALL");
// prints "BASEBALL"
System.out.println(mine.toString());
// prints true
System.out.println(mine.equals(hats.valueOf("BASEBALL"));
Como mis requisitos eran que tenía que ser posible agregar miembros a la enumeración en tiempo de ejecución, también implementé esa funcionalidad:
hats.addEnum("BATTING_PRACTICE");
HatEnumRepository.storeEnum(hats);
hats = HatEnumRepository.retrieve();
HatEnumValue justArrived = hats.valueOf("BATTING_PRACTICE");
// file now reads:
// 1 --> BASEBALL
// 2 --> BRIMLESS
// 3 --> INDIANA_JONES
// 4 --> BATTING_PRACTICE
Lo llamé el "patrón" de Enumeración Dinámica, y leíste sobre el diseño original y su edición revisada .
La diferencia entre los dos es que la edición revisada fue diseñada después de que comencé a asimilar OO y DDD. El primero que diseñé cuando todavía estaba escribiendo DDD nominalmente procedimental, bajo presión de tiempo no menos.
Necesitaba hacer algo como esto (para fines de pruebas unitarias), y me encontré con esto: el EnumBuster: http://www.javaspecialists.eu/archive/Issue161.html
Permite agregar, eliminar y restaurar valores enum.
Editar : Acabo de empezar a usar esto, y descubrí que hay algunos cambios leves necesarios para Java 1.5, que actualmente estoy atascado:
- Agregue una matriz de métodos auxiliares estáticos (por ejemplo, tome estas versiones 1.6: http://www.docjar.com/html/api/java/util/Arrays.java.html )
- Cambie EnumBuster.undoStack a Stack
<Memento>
- En undo (), cambie undoStack.poll () para undoStack.isEmpty ()? null: undoStack.pop ();
- La cadena VALUES_FIELD debe ser "ENUM $ VALUES" para las enums de java 1.5 que he intentado hasta ahora
No, se supone que las enumeraciones son una enumeración estática completa.
En tiempo de compilación, es posible que desee generar su archivo .java enum a partir de otro archivo fuente de algún tipo. Incluso podría crear un archivo .class como este.
En algunos casos, es posible que desee un conjunto de valores estándar, pero permita la extensión. La forma habitual de hacerlo es tener una interface
para la interfaz y una enum
que implemente esa interface
para los valores estándar. Por supuesto, pierde la capacidad de switch
cuando solo tiene una referencia a la interface
.
Podría tratar de asignar propiedades al ENUM que intenta crear y calcular estáticamente utilizando un archivo de propiedades cargado. Big hack, pero funciona :)
Puede cargar una clase Java desde la fuente en tiempo de ejecución. (Usando JCI, BeanShell o JavaCompiler)
Esto le permitiría cambiar los valores de Enum como lo desee.
Nota: esto no cambiaría ninguna clase que hiciera referencia a estas enumeraciones, por lo que podría no ser muy útil en la realidad.