2011-12-11 20 views
12

Digamos que tengo un archivo cuyo formato es XML básica, así:Generación de enumeraciones dinámicamente

<?xml version="1.0"?> 
<enum-set> 
    <enum> 
     <name>SomeEnum</name> 
     <values> 
      <value> 
       <name>SOMEVALUE</name> 
       <displayText>This is some value</displayText> 
      </value> 
      ... more values ... 
     </values> 
    </enum> 
    ... more enums ... 
</enum-set> 

y quería convertir SomeEnum en algo como esto en tiempo de ejecución:

public enum SomeEnum implements HasDisplayText { 
    SOMEVALUE("This is some value"), 
    ... more values ...; 

    private String displayText; 

    SomeEnum(String displayText) { 
     this.displayText = displayText; 
    } 

    @Override 
    public String getDisplayText() { 
     return displayText; 
    } 
} 

.. .y luego pase la enumeración recién creada enum SomeEnum alrededor de mi aplicación. ¿Cómo podría lograr algo como esto? ¿Es factible?

Respuesta

14

Lo que estás tratando de hacer no tiene mucho sentido. Enums son realmente solo para el beneficio del tiempo de compilación, ya que representan un conjunto fijo de constantes. En tiempo de ejecución, ¿cuál sería el significado de una enumeración generada dinámicamente? ¿Cómo sería esto diferente de un objeto simple? Por ejemplo:

public class Salutation implements HasDisplayText { 

    private String displayText; 

    private Salutation(String displayText) { 
     this.displayText = displayText; 
    } 

    @Override 
    public String getDisplayText() { 
     return displayText; 
    } 

    public static Collection<Salutation> loadSalutations(String xml) { 
     //parse, instantiate, and return Salutations 
    } 
} 

Su XML se ha podido analizar en recién instanciada Salutation objetos, que podrían ser almacenados en algún Collection o de otra forma utilizado por su programa. Observe en mi ejemplo, he restringido la creación de Salutation dándole un constructor private - en este caso la única forma de recuperar instancias es llamando al método de fábrica que toma su XML. Creo que esto logra el comportamiento que estás buscando.

+0

tiene sentido. Pregunté sobre enumeraciones específicamente porque mi jerarquía tiene muchas de ellas ahora (no una cantidad absurda, solo unas pocas) y esperaba eliminarlas. –

+0

@Chris - Espera, ¿así que tu pregunta sobre la generación de código, o crearlos en tiempo de ejecución? –

+0

Realmente se trata de crearlos en tiempo de ejecución. Supongo que eso es diferente. –

6

realidad es posible crear instancias de enumeración dinámicamente, pero es un corte total, el yo no lo aconsejaría a todos - tal vez usted está malentendido la naturaleza de un enum, que es una característica de tiempo de compilación de la idioma, y ​​se supone que no debes agregar/eliminar instancias en el tiempo de ejecución.

De todos modos, si está interesado en el truco para crear instancias enum dinámicamente, eche un vistazo a este article.

0

De acuerdo con Oscar Lopez. Esto es lo que hice, una especie de truco.

public static enum Setter { 

    DYNAMIC_ENUM_EXAMPLE { 

     @Override 
     public String setGetValue(String yourValue) { 
      return "prefix " + yourValue + " postfix"; 
     } 
    }; 
    public abstract String setGetValue(String value); 
} 

, usted puede obtener el valor de la siguiente manera:

Setter.DYNAMIC_ENUM_EXAMPLE.setGetValue("namaste") 

Salida:

prefix namaste postfix 
0

dinámicos enumeraciones es la respuesta a su problema:

public abstract class DEnum<E extends DEnum<E>> implements Comparable<E>, Serializable { 

Esta clase tiene una firma similar al estándar Enu m clase. Tiene un constructor protegido para permitir la creación de instancias en clases Enum concretas.Por ejemplo:

public class YesNo extends DEnum<YesNo> { 

    public final static YesNo YES = new YesNo(); 
    public final static YesNo NO = new YesNo(); 

La clase DEnum conoce los nombres de los miembros de la introspección:

String name = YesNo.YES.getName(); 
YesNo yes = YesNo.get(YesNo.class, name); 
assert (yes == YesNo.YES); 

No es un captador escrito que recupera todos los artículos:

YesNo[] items = yes.getItems(); 
assert (items.length == 2); 

Permite a agregar miembros dinámicamente en tiempo de ejecución con (desde la base de datos o desde el archivo):

YesNo maybe = getOrCreateIfNotExists(YesNo.class, "MAYBE"); 
items = yes.getItems(); 
assert (items.length == 3); 

que tienen el mismo comportamiento que los miembros estáticos:

YesNo unknown = YesNo.get(YesNo.class, "MAYBE"); 
assert (unknown == maybe); 
+0

Debe incluir un enlace a la implementación de 'DEnum', o publicarlo aquí –