2012-07-15 5 views
6

En supposant que j'ai un ENUM de base comme:Java: accepter générique uniquement les types enum

public enum Color { Red, Green, Blue} 

Comment peut-on écrire une classe générique qui accepte que des « classes ENUM » de sorte qu'une instanciation concrète de cette classe générique pourrait ressembler à MyClass<Color>?

Edit:

Quelle veulent vraiment faire est d'écrire une classe abstraite générique contenant une fonction renvoyant toutes les « entrées » enum liste:

public abstract class EnumListBean<E extends Enum<E>> { 

    public List<E> getEnumList() { 
     return Arrays.asList(E.values()); 
    } 

} 

Alors que Day.values() est disponible E.values() est ne pas. Qu'est-ce que je fais mal ici?

+0

Pas sa mise en œuvre ne devrait pas se limiter à un seul type de béton, mais ENUM à des types enum arbitraires. Je viens d'utiliser 'Day' pour décrire plus concrètement ce que je veux. – Paranaix

Répondre

5
public class EnumAcceptor<E extends Enum<E>> { 
    ... 
} 

Utilisez E comme un type dans votre classe.

1

Un enum déclare réellement une classe dérivée de Enum. En tant que tel, vous pouvez utiliser:

public class MyClass<T extends Enum> { } 
+2

Vous mélangez des génériques et des types bruts. –

4

Voir Istvan Devai pour la réponse à la question d'origine. Pour le suivi, les méthodes comme values() sont des méthodes statiques, donc vous n'avez pas de chance d'essayer d'obtenir cela à partir d'un paramètre générique. En tant que solution médiocre, vous pouvez passer l'objet Class de l'enum dans le constructeur. et utilisez Class.getEnumConstants. Mais vous pourriez aussi bien passer MyEnum.values() dans le constructeur plutôt que dans la classe, et ainsi éviter toute réflexion. C'est vraiment dommage qu'il n'y ait pas de métaclasse enum en bonne et due forme.

0

Notez que la solution @ Istvan ne peut accepter que éléments du enum, ce qui est bien si c'est tout ce que vous voulez.

Bien que vous ne pouvez pas passer le enum lui-même comme un paramètre (parce qu'il n'a pas en fait un objet équivalent), vous pouvez spécifier que vous devez recevoir le class du enum dans votre constructeur et d'en tirer les détails de la enum de ce qui suit:

public class EnumAcceptor<E extends Enum<E>> { 
    public EnumAcceptor(Class<E> c) { 
    // Can get at the enum constants through the class. 
    E[] es = c.getEnumConstants(); 
    } 

    enum ABC { 
    A, B, C; 
    } 

    public static void main(String args[]) { 
    EnumAcceptor<ABC> abcAcceptor = new EnumAcceptor<ABC>(ABC.class); 
    } 
} 
+0

Oups - duplicata du message de @ Tom - désolé Tom :( – OldCurmudgeon

0

Vous ne pouvez pas utiliser E.values() en raison de l'effacement de type - le type de E n'est pas disponible lors de l'exécution.

Pour le cas précis dans votre question, vous êtes probablement mieux d'utiliser Guava « s Lists.newArrayList:

List<Color> days = Lists.newArrayList(Color.values()); 
Questions connexes