Las enumeraciones de Java son geniales. Así son los genéricos. Por supuesto, todos conocemos las limitaciones de este último debido al tipo de borrado. Pero hay una cosa que no entiendo, ¿por qué no puedo crear una enumeración como esta:
public enum MyEnum<T> {
LITERAL1<String>,
LITERAL2<Integer>,
LITERAL3<Object>;
}
Este parámetro de tipo genérico <T>
a su vez podría ser útil en varios lugares. Imagine un parámetro de tipo genérico para un método:
public <T> T getValue(MyEnum<T> param);
O incluso en la clase enum:
public T convert(Object o);
Ejemplo más concreto # 1
Dado que el ejemplo anterior puede parecer demasiado abstracto para algunos, aquí hay un ejemplo más real de por qué quiero hacer esto. En este ejemplo quiero usar
- Enums, porque entonces puedo enumerar un conjunto finito de claves de propiedad
- Genéricos, porque entonces puedo tener seguridad de tipos a nivel de método para almacenar propiedades
public interface MyProperties {
public <T> void put(MyEnum<T> key, T value);
public <T> T get(MyEnum<T> key);
}
Ejemplo más concreto # 2
Tengo una enumeración de tipos de datos:
public interface DataType<T> {}
public enum SQLDataType<T> implements DataType<T> {
TINYINT<Byte>,
SMALLINT<Short>,
INT<Integer>,
BIGINT<Long>,
CLOB<String>,
VARCHAR<String>,
...
}
Cada enum literal obviamente tendría propiedades adicionales basadas en el tipo genérico <T>
, al mismo tiempo que sería una enumeración (inmutable, singleton, enumerable, etc., etc.)
Pregunta:
¿Nadie pensó en esto? ¿Es esta una limitación relacionada con el compilador? Teniendo en cuenta el hecho de que la palabra clave " enum " se implementa como azúcar sintáctico, que representa el código generado para la JVM, no entiendo esta limitación.
¿Quién me puede explicar esto? Antes de responder, considere esto:
- Sé que los tipos genéricos se borran :-)
- Sé que hay soluciones alternativas al usar objetos de clase. Son soluciones alternativas.
- Los tipos genéricos resultan en conversiones de tipo generadas por el compilador cuando corresponda (por ejemplo, al llamar al método convert ()
- El tipo genérico <T> estaría en la enumeración. Por lo tanto, está obligado por cada uno de los literales de la enumeración. Por lo tanto, el compilador sabría qué tipo aplicar al escribir algo como
String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
- Lo mismo se aplica al parámetro de tipo genérico en el
T getvalue()
método. El compilador puede aplicar la conversión de tipos al llamarString string = someClass.getValue(LITERAL1)
enum
conviértalo en un lenguaje de "enumeración segura de tipos" que usamos antes de Java 1.5. De repente, puede tener sus miembros de enumeración parametrizados. Eso es probablemente lo que voy a hacer ahora.