Pourquoi ne pas Java enum littéraux être en mesure d'avoir des paramètres de type générique?

Java enums sont grands. Donc, sont des génériques. Bien sûr, nous connaissons tous les limites de cette dernière en raison de type de l'effacement. Mais il y a une chose que je ne comprends pas, Pourquoi ne puis-je pas créer un enum comme ceci:

public enum MyEnum<T> {
    LITERAL1<String>,
    LITERAL2<Integer>,
    LITERAL3<Object>;
}

Ce paramètre de type générique <T> pourrait alors être utile dans différents endroits. Imaginez un paramètre de type générique à une méthode:

public <T> T getValue(MyEnum<T> param);

Ou même dans l'énumération de la classe elle-même:

public T convert(Object o);

Exemple plus concret n ° 1

Depuis l'exemple ci-dessus peut sembler trop abstrait pour certains, voici un exemple de pourquoi je veux faire ce. Dans cet exemple, je veux utiliser

  • Enums, parce que je peux énumérer un ensemble fini de propriété touches
  • Génériques, parce que je peux avoir de la méthode de niveau de type de sécurité pour le stockage des propriétés
public interface MyProperties {
     public <T> void put(MyEnum<T> key, T value);
     public <T> T get(MyEnum<T> key);
}

Exemple plus concret n ° 2

J'ai une énumération des types de données:

public interface DataType<T> {}

public enum SQLDataType<T> implements DataType<T> {
    TINYINT<Byte>,
    SMALLINT<Short>,
    INT<Integer>,
    BIGINT<Long>,
    CLOB<String>,
    VARCHAR<String>,
    ...
}

Chaque enum littérale serait évidemment d'avoir des propriétés supplémentaires basés sur le type générique <T>, alors que dans le même temps, être un enum (immuable, singleton, énumérable, etc. etc.)

Question:

Ne pas penser à cela? Est-ce un compilateur limitation? Compte tenu du fait que le mot-clé "enum" est mis en œuvre en tant que sucre syntaxique, représentant le code généré pour la JVM, je ne comprends pas cette limitation.

Qui peut il m'expliquer? Avant de vous répondre, pensez à ceci:

  • Je sais que les types génériques sont effacés 🙂
  • Je sais qu'il existe des solutions de contournement en utilisant des objets de la Classe. Ils sont des solutions de contournement.
  • Types génériques résultat généré par le compilateur le type de jette, le cas échéant (par exemple, lors de l'appel de la fonction convert() la méthode
  • Le générique de type <T> serait sur les enum. Par conséquent, il est lié par chacune des enum littéraux. Donc le compilateur sait, à quel type à appliquer lors de l'écriture de quelque chose comme String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
  • La même chose s'applique pour le paramètre de type générique dans le T getvalue() méthode. Le compilateur peut appliquer la conversion de type lors de l'appel de String string = someClass.getValue(LITERAL1)
  • Je ne comprends pas cette limitation soit. Je suis tombé sur cette récemment où mon enum contenus différents "Comparables" types, et avec les médicaments génériques, la comparaison des types du même genre, peut être comparé sans avertissements qui doivent être supprimés (même si au moment de l'exécution de la bonne, lesquels devraient être comparés). Je pourrais avoir réussi à se débarrasser de ces mises en garde par l'utilisation d'un type lié dans l'enum pour spécifier le type comparable a été pris en charge, mais à la place j'ai dû ajouter de la SuppressWarnings annotation - pas moyen de contourner cela! Depuis compareTo ne jeter une classe cast exception de toute façon, c'est ok, je suppose, mais quand même...
  • J'ai voté pour fermer ma propre question comme étant "non constructif". Cette question ne peut être répondu sans commencer à disserter sur le PLAN de décisions au sujet de la langue de conception ou de ma propre intention (par exemple, à l'origine, accepté, mais a supprimé la réponse, pour ceux qui peuvent voir supprimé réponses)...
  • (+1) je suis juste au milieu, à essayer de fermer un type de la sécurité de l'écart dans mon projet d'arrêté morts par cette limitation arbitraire. Il suffit de considérer ceci: tournez le enum dans un "typesafe enum" l'idiome nous avons utilisé avant de Java 1.5. Tout à coup, vous pouvez avoir votre enum membres paramétrée. C'est probablement ce que je vais faire maintenant.
  • C'est une chose que vous pouvez faire, mais vous perdrez toutes les awesome enum caractéristiques qui sont cuits dans le langage et la JDK. Par exemple switch de soutien, ou EnumSet et EnumMap
  • Je sais, c'est mal 🙂 En fait, j'ai dû abandonner pour l'une des deux énumérations où j'ai voulu l'appliquer.
  • J'ai du mal à penser à un scénario qui pourrait être utile. Avez-vous un plus concrète scénario?
  • Mise à jour de la question avec un exemple concret à partir de jOOQ, alors qu'il aurait été très utile dans le passé.
  • Je vois votre point de maintenant. Ressemble à une cool une nouvelle fonctionnalité. Peut-être devriez vous suggérons projet de pièce de monnaie de la liste de diffusion je vois d'autres propositions intéressantes, là, sur les énumérations, mais pas une comme la vôtre.
  • Tout à fait d'accord. Enum sans les génériques sont paralysés. Votre cas #1 est aussi la mienne. Si j'ai besoin d'générique enum j'abandonne JDK5 et le mettre en œuvre de plain old Java 1.4 style. Cette approche a également l'avantage supplémentaire: je ne suis pas obligé d'avoir toutes les constantes dans une catégorie ou d'un même package. Ainsi, le paquet par la fonctionnalité de style est en fait beaucoup mieux. C'est juste parfait pour la configuration comme "enum" - les constantes sont répartis dans les paquets en fonction de leur logique du sens (et si je veux les voir tous, j'ai le type de hiérarchie montré).
  • C'est que la liste est encore actif? De toute façon, je n'ai pas fait de super expérience sur ces listes dans le passé...
  • En fait, c'est vraiment une bonne question. C'est une honte de voir que pratiquement toutes les réponses sont soit manquants, le point ou le non-respect entièrement le problème. Dans un sens, je suppose que c'est normal, cependant, de voir comme il semble y avoir pas de réponse évidente.
  • Une bonne idée, mais il ne fait qu'ajouter de la JLS, faire des travaux d'entretien et de nouvelles fonctionnalités beaucoup plus fort, donc la résistance. Java est déjà piraté en avant et en arrière en arrière des raisons de compatibilité, en gardant pur est je pense un #1 prio maintenant. Donc c'est un argument que, si vous avez besoin de ce niveau de complexité de votre enums, vous devriez peut-être ce modèle avec OO au lieu.
  • Qu'entendez-vous par "garder pure". Aussi, comment sont génériques enums a) complexes et b) de ne pas OO? D'ailleurs, avez-vous vérifié openjdk.java.net/jeps/301?

InformationsquelleAutor Lukas Eder | 2010-11-27