2012-07-26 10 views
13

Estoy intentando inicializar una clase genérica con todos los valores disponibles de un Enum. Así es cómo me gustaría que funcione:Use Enum.values ​​con clase genérica que se extiende Enum

public class MyClass<E extends Enum<E>> { 

    E[] choices; 

    public MyClass() { 
     choices = E.values(); 
    } 

Sin embargo, la llamada a E.values no es aceptada en Eclipse diciendo que este método no está definido para este E.

El uso de este constructor vez se acepta, pero requiere la persona que llama para proporcionar los valores:

public MyClass(E[] e) { 
    choices = e; 
} 

En la documentación que encontré:

Los tipos de enum del lenguaje de programación Java son mucho más potentes que sus contrapartes en otros idiomas. La declaración enum define una clase (llamada tipo enum). El cuerpo de la clase enum puede incluir métodos y otros campos. El compilador agrega automáticamente algunos métodos especiales cuando crea una enumeración. Por ejemplo, tienen un método de valores estáticos que devuelve una matriz que contiene todos los valores de la enumeración en el orden se declaran.

¿Hay alguna forma de solucionar este problema?

Respuesta

20

Su mejor opción es, probablemente, pasar un Class de la enumeración deseada al constructor. (Ver cómo un EnumMap se construye por ejemplo.)

continuación, puede utilizar clazz.getEnumConstants() de hacerse con las constantes.

3

Su primer fragmento de código no funciona debido a cómo se implementa Generics en Java, y debido a un fenómeno conocido como type erasure. Debido a esto, la JVM no tendrá idea de cuál es el tipo de E cuando el programa se está ejecutando.

Probablemente se podría hacer algo como esto en el constructor MyClass 's:

public MyClass(E type) { 
    choices = type.getDeclaringClass().getEnumConstants(); 
} 
+0

creo que esto no tiene nada que ver con el tipo de borrado. La causa del problema es que el método 'public static E [] values ​​()' no es un método presente en la clase 'java.lang.Enum'. [La especificación del lenguaje Java] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2) explica que este método, sin embargo, se genera de forma sintética para todas las enums. Entonces, en mi opinión, el método está presente en cualquier referencia concreta de una enumeración, pero no en la clase enum misma. –

Cuestiones relacionadas