Esta versatilidad se debe a que, en Java, los enumerados son clases, en toda su extensión.
Enumerados básicos
Podemos tener enumerados muy básicos. Consisten en una mera enumeración de elementos:
public enum EnumeradoBasico () {
item1,
item2,
item3,
}
Poco que explicar aquí.Enumerados con Valor
No hay una forma definida para dar un valor a un enumerado, pero podemos realizarlo mediante un constructor:
public enum EnumeradoBasico () {
item1(0),
item2(1),
item3(200),
;
private int value;
EnumeradoBasico(int v) {
this.value = v;
}
}
Como veréis he creado un constructor que admite un valor. Almaceno este valor en una variable privada. Como no tengo el constructor por defecto, los propios valores del enumerado tienen que crearse con un valor.
Por esta misma razón, los enumerados admiten compararse mediante == en lugar de utilizar equals. Y por esta misma razón, pueden utilizarse en un switch. Si os lo curráis un poquitín, podéis utilizar un enumerado para comparar cadenas en un switch (vale, no en todos los casos).
Interfaces
Como bien dije al principio, los enumerados son clases y, como tales, pueden implementar clases:
public enum Enumerado implements Serializable () {
item1(0),
item2(1),
item3(200),
;
private int value;
EnumeradoBasico(int v) {
this.value = v;
}
}
Sin embargo, mucho me temo que no pueden extender de una clase abstracta. Esto se debe a que todos los enumerados extienden de java.lang.Enum, y como en Java no hay herencia múltiple, no se puede extender nada más.Lo que sí puede hacerse es sobreescribir algún método, incluso métodos que están definidos en el tipo enumerado se pueden sobreescribir en cada uno de los valores:
public enum Enumerado {
item1(0) {
@Override
public void realizarTarea() {
// Aquí va el código
}
;
},
item2(1) {
@Override
public void realizarTarea() {
// Aquí va el código
}
;
}
;
private int value;
Enumerado(int v) {
this.value = v;
}
public abstract void realizarTarea();
}
La desventaja de utilizar este método es que puede oscurecer bastante el código.Búsquedas invertidas
Hay ocasiones en las que no solo necesitamos asociar un número a un enumerado, sino también saber qué número se corresponde con el enumerado. Habitualmente esto suele traducirse en switchs enormes y engorrosos, pero es mucho más sencillo de lo que parece:
public enum NaveInterestelar {
PATRULLERA(-1),
ESCOLTA(0),
RESERVA(1000),
;
private int value;
private static final Map lookup
= new HashMap();
static {
for (NaveInterestelar each : EnumSet.allOf(NaveInterestelar.class)) {
lookup.put(each.value, each);
}
}
NaveInterestelar(int value) {
this.value = value;
}
public static NaveInterestelar get(int v) {
return lookup.get(v);
}
public int getCode() {
return value;
}
}
Y esto nos vale como un ejemplo completo :DComo veréis, podemos obtener un enumerado a partir de un entero (get)o bien el entero a partir del enumerado (getCode).
Opinión personal
Los tipos enumerados en Java son muy potentes. Tan potentes como para poder tener funcionalidad por sí mismos. Dicho de otra manera, un enumerado Java NO es un enumerado, sino una unidad de computación como pueda ser una clase.
Esta potencia es una espada de Damocles: por un lado, ofrece mucha funcionalidad. Por otro, el precio es terrible, ya que no suele esperarse esta funcionalidad de un "simple" enumerado.
Además, está la oportunidad de utilizar cadenas (String) en las instrucciones switch, lo que puede quedar mucho más bonito que utilizar ifs anidados.
Personalmente creo que había formas más elegantes de ofrecer parte de esta funcionalidad, y que hubieran sido más acertadas que con tipos enumerados tan complejos. Pero no soy quien para decir nada :D
Enlaces
Podéis consultar la propia documentación de sun/Oracle o bien el post de Brennan Spies titulado "Making the Most of Java 5.0: Enum Tricks".Espero que los encontréis interesantes.
Unas apreciaciones como crítica constructiva, aunque ya adelanto que veo muy trabajado el artículo y bien formulado.
ResponderSuprimirDesde el feed, no se ven los ejemplos de código de artículo (supongo que porque serán referencias a github desde algún plugin).
No estoy muy deacuerdo con decir "No os preocupéis por la gestión de memoria". Es algo primordial (más si has sido formado como ingeniero), sobretodo si estas haciendo ejemplos de algo tan delicado como un parser. Donde perfectamente puedes tener una gran entrada y que se desborde de memoria tu aplicación.
Me parece que los tipos enumerados siempre han sido usados como algo minimalista, como forma de simplificar algo tan complicado como recordar números o tipos de valores. Añadir métodos o funcionalidad extra, creo que le hace perder el encanto de simplicidad y puede derivar en un código más complejo de tratar y de comprender. Pero como todo, depende de la utilización y contar con la funcionalidad es un extra añadido aunque no sea en mi opinión el sitio más adecuado de implementarlo.
Hola!
ResponderSuprimirComentarios así siempre son bienvenidos.
Lo que me cuentas del feed es un temilla, pero es que no se me ocurre la manera de solucionarlo. Como dices, son enlaces a github, donde está el código. Esto me da dos ventajas principales: Control de versiones y resaltado de sintaxis. Y una desventaja: los ejemplos están separados del código. Tengo que pensármelo (acepto sugerencias).
Respecto a la gestión de memoria... Temo que está un poco sacado de contexto, fruto también de que yo lo he dejado un poco abierto. Me refiero a que no es necesario preocuparse por la memoria utilizada por cada instancia de enumerado, ya que la JVM sólo instanciará un objeto de cada valor. Evidentemente, en Java hay que tener mucho cuidado con la memoria, ya que ofrece azúcar sintáctico algo envenenado (como el operador '+' de las cadenas).
Como ves en la conclusión, no puedo estar más de acuerdo de que darle "inteligencia" a los enumerados es un riesgo. En algunas ocasiones puede venir muy bien, pero en otras puede ser un completo desastre.
Un saludo y gracias por el comentario.
Hola de nuevo.
ResponderSuprimirCreo que he conseguido que los feeds salgan más o menos bien, manteniendo el site con una apariencia decente. Pierdo el control de versiones, pero gano que está todo el site junto.
Muchas gracias de nuevo.