¿Qué significa enum en java?
Introducción al tipo Enum
El tipo enumerado (Enumeated Type) apareció muy temprano en los lenguajes de programación. Se utiliza para incluir un grupo de valores similares en un tipo. . El nombre de este tipo de enumeración se definirá como un descriptor de tipo único, que es similar a la definición de una constante. Sin embargo, en comparación con los tipos constantes, los tipos de enumeración pueden proporcionar un rango de valores mayor para las variables declaradas.
Por ejemplo, si quieres dibujar siete colores para el arcoíris, puedes hacerlo mediante una definición constante en un programa Java.
Lista 1. Definición de constantes Public?static?class?RainbowColor?{?
//?Definiciones de constantes para los siete colores de rojo, naranja, amarillo, verde, azul y morado
public?static?final?int?RED?=?0;?
public?static?final?int?ORANGE?=?1;?
público?estático?final ?int?AMARILLO?=?2;?
público?estático?final?int?VERDE?=?3;?
público?estático? final?int?CYAN?= ?4;?
público?static?final?int?BLUE?=?5;?
público?static?final?int?PURPLE? =?6;? }
Al usarlo, puede hacer referencia directamente a estas constantes en el programa. Sin embargo, todavía existen algunos problemas con este enfoque.
Tipo no seguro
Dado que el valor correspondiente de la constante de color es un número entero, es muy probable que se pase un valor entero arbitrario a la variable de color durante la ejecución del programa, provocando un error. .
Sin espacio de nombres
Dado que las constantes de color son solo atributos de la clase, debes acceder a ellas a través de la clase cuando las uses.
Pobre coherencia
Debido a que las enumeraciones de enteros son constantes en tiempo de compilación, una vez completado el proceso de compilación, los valores enteros se escribirán directamente en todos los lugares a los que hacen referencia el cliente y el servidor. De esta manera, cuando modifica el valor entero de enumeración anterior o agrega un nuevo valor de enumeración, es necesario volver a compilar todo el código al que se hace referencia; de lo contrario, se producirán errores en tiempo de ejecución.
El tipo no tiene sentido
Dado que los valores de enumeración de colores son solo valores enteros sin ningún significado, si depura en tiempo de ejecución, encontrará mucha magia en el registra Números, pero aparte de los propios programadores, es difícil para otros comprender sus secretos.
Cómo definir el tipo de enumeración
Para mejorar las deficiencias del lenguaje Java en este sentido, cuando se lanzó la versión 5.0 SDK, se agregaron tipos de enumeración a nivel de lenguaje. La definición de un tipo de enumeración también es muy simple. Simplemente use la palabra clave enum más el nombre y el cuerpo del valor de enumeración entre llaves. Por ejemplo, el color del arco iris mencionado anteriormente se puede redefinir usando el nuevo método enum: enum? ?ROJO,?NARANJA,?AMARILLO,?VERDE,?CIAN,?AZUL,?PÚRPURA?}
De la forma de definición anterior, parece que el tipo de enumeración en Java es muy simple, pero de hecho. , la especificación del lenguaje Java le da al tipo de enumeración una función muy poderosa. No solo convierte simplemente un valor entero en un objeto, sino que también transforma la definición del tipo de enumeración en una definición de clase completamente funcional. Esta extensión de definición de tipo permite a los desarrolladores agregar métodos y propiedades al tipo de enumeración e implementar cualquier interfaz.
Además, la plataforma Java también proporciona implementaciones de alta calidad para el tipo Enum, como la implementación predeterminada de las interfaces Comparable y Serializable, por lo que los desarrolladores generalmente no necesitan preocuparse por estos detalles.
Volviendo al tema de este artículo, ¿qué beneficios puede aportar a nuestro desarrollo la introducción de tipos de enumeración? Uno de los beneficios más directos es ampliar el alcance de uso de las declaraciones de cambio. Antes de 5.0, el valor de switch en Java solo podía ser tipos simples, como int, byte, short, char. Con tipos de enumeración, se pueden usar objetos. De esta manera, la selección de control del programa se vuelve más conveniente, vea el siguiente ejemplo:
Listado 2. Definir el tipo de enumeración // Definir el tipo de enumeración de los siete días de la semana public?enum? WeekDayEnum?{ ?Lunes, ?Martes, ?Miércoles, ?Jueves, ?Viernes, ?Sábados, ?Domingos?}? //Leer la información del día WeekDayEnum?today?=?readToday(); //Seleccionar según la fecha Cambio de actividad (hoy)? {? Lun:?hacer?algo;?descansar;? Martes:?hacer?algo;?descansar;? Miércoles:?hacer?algo;?descansar;? ?descanso ;? Vie: ?hacer?algo;?descanso;? Sábado:?jugar?juego?deportes;?descanso;? Sol:?tener?un?descanso;? estas monedas Para cualquier fecha determinada, la JVM construirá una instancia de objeto simple en correspondencia uno a uno durante el tiempo de ejecución. Estos objetos tienen una identidad única, similar a un valor entero, y la instrucción switch realiza saltos de ejecución basados en esto.
Cómo personalizar el tipo de enumeración
Además del formulario de definición de enumeración más común anterior, si necesita agregar algunas funciones complejas al tipo de enumeración, también puede usar una clase -Como definición. Personaliza la enumeración.
Por ejemplo, si desea agregar atributos al tipo de enumeración, puede definirlo de la siguiente manera:
Listado 3. Tipo de enumeración personalizado // Definición de tipo de enumeración inicial RSS (Really Simple Syndication) ¿enumeración pública? NewsRSSFeedEnum?{?
//?YAHOO Top News?RSS?Seeds
YAHOO_TOP_STORIES("/rss/topstories"),?
//CBS ? ¿Titulares de noticias?RSS?Seed
CBS_TOP_STORIES("/CBSNewsMain?format=xml"),?
//?Titulares de noticias de Los Angeles Times?RSS?Seed
LATIMES_TOP_STORIES("/latimes/news?format=xml");?
//?Atributos de la dirección RSS del objeto de enumeración
private?String?rss_url;
//?Constructor de objetos de enumeración
private?NewsRSSFeedEnum(String?rss)?{?
this.rss_url?=?rss;? >
}?
//?Método del objeto de enumeración para obtener la dirección RSS
public?String?getRssURL()?{?
return? this.rss_url;?
}? }
El tipo de enumeración de los titulares de noticias anteriores agrega un atributo de dirección RSS para registrar la dirección de acceso de los titulares de noticias. Al mismo tiempo, el valor de la dirección de acceso RSS debe pasarse externamente, por lo que es necesario definir un constructor para inicializar esta propiedad. Además, es necesario proporcionar un método externo para leer la dirección RSS.
Cómo evitar el uso incorrecto de Enum
Sin embargo, hay algunas cosas a tener en cuenta al usar Enum:
El tipo de enumeración no admite el público y constructores de modificadores protegidos, por lo que el constructor debe ser privado o amigable. Debido a esto, el objeto de enumeración no se puede inicializar en el programa llamando directamente a su constructor.
Al definir el tipo de enumeración, si es un tipo simple, entonces el último valor de enumeración no necesita ir seguido de ningún símbolo, pero si hay un método personalizado, entonces el último valor de enumeración y el; El siguiente código debe utilizar un punto y coma' ;' separado por comas o espacios.
Dado que el valor del tipo de enumeración en realidad está representado por un objeto construido durante el tiempo de ejecución, en el entorno del clúster, cada máquina virtual construirá un objeto de enumeración sinónimo. Por lo tanto, debe prestar atención al realizar operaciones de comparación. Si utiliza directamente el operador de signo igual ('=='), estos valores de enumeración aparentemente idénticos no deben ser iguales, porque no son la misma instancia de objeto.
Mire el siguiente ejemplo:
Listado 4. Evite el uso incorrecto de Enum Ejemplo // ¿Definir un tipo de enumeración para el paquete de siete días de la semana example.enumeration.codes; ?público?enum?WeekDayEnum?{?
lun(1), ?martes(2), ?miércoles(3), ?jueves(4), ?viernes(5), ?sáb(6) , ?Sol (7);?
privado?int?index;?
WeekDayEnum(int?idx)?{?
this.index?= ?idx; ?
}?
público?int?getIndex()?{?
return?index;?
} ? }/ /?Programa cliente, transferir un valor de enumeración al paquete del lado del servidor?example.enumeration.codes;?import?java.io.IOException;?import?java.io.ObjectOutputStream;?import?java.io. OutputStream;? importar?java.net.InetSocketAddress;? importar?java.net.Socket;? importar?java.net.UnknownHostException;? público?clase?EnumerationClient?{?
público?estático? ?main(String...?args)?throws?UnknownHostException,?IOException?{?
Socket?socket?=?new?Socket(); //Establecer una conexión con el servidor
p>socket.connect(new?InetSocketAddress("127.0.0.1",?8999));?
//?Obtener el flujo de salida de la conexión
OutputStream? os?=?socket.getOutputStream();?
ObjectOutputStream?oos?=?new?ObjectOutputStream(os); //Pasar el valor de enumeración del viernes al servidor
oos.writeObject(WeekDayEnum.Fri);?
oos.close();?
os.close();?
socket .close ();?
}? }? //Programa del lado del servidor, aplica los valores de enumeración recibidos del cliente al paquete de procesamiento lógico?example.enumeration.codes;?import?java .io.*;? import?java.net.ServerSocket;? import?java.net.Socket;?public?class?EnumerationServer?{?
public?static?void?main(String.. ?args)?lanza?IOException,?ClassNotFoundException?{?
Servidor.
Socket?server?=?new?ServerSocket(8999);? //Establecer una conexión de red del lado del servidor escuchando
Socket?socket?=?server.accept();? conexión Obtener el flujo de entrada
InputStream?is?=?socket.getInputStream();?
ObjectInputStream?ois?=?new?ObjectInputStream(is);? sacar del cliente El valor de enumeración pasado desde el cliente
WeekDayEnum?day?=?(WeekDayEnum)?ois.readObject(); //Utilizar el método de comparación de valores para comparar objetos de enumeración
if?(day?==?WeekDayEnum.Fri)?{?
System.out.println("cliente?Friday?enum?value?is?same?as?server's");?
p>}?else?if?(day.equals(WeekDayEnum.Fri))?{?
System.out.println("cliente?Friday?enum?value? es?igual?a?servidor");?
}?else?{?
System.out.println("cliente?Viernes?enum?valor?no? ¿igual? que? el servidor");?
}? //¿Utilizar?switch?método para comparar objetos de enumeración
switch?(día)?{?
caso ?Mon:?
System.out.println("Do?Monday?work");?
descanso;?
caso?Tue :?
System.out.println("¿El martes?trabajo");?
descanso;?
caso?Miércoles:?
System.out.println("¿Do?Miércoles?trabajo");?
descanso;?
caso?Jueves:?
Sistema .out. println("¿El jueves?trabajo");?
descanso;?
caso?Viernes:?
System.out.println( "¿Hacer? Viernes?trabajo");?
descanso;?
caso?Sábado:?
System.out.println("¿Hacer?Sábado? trabajo") ;?
romper;?
caso?Sol:?
System.out.println("¿Do?Domingo?trabajo");?
descanso;?
predeterminado:?
System.out.println("¿No?sé?cuál?es?día"); ? p>
romper;?
}?
ois.close();?
is.close();? p>
socket.close();?
>}? }
El resultado de la impresión es el siguiente:
el valor de enumeración del viernes del cliente es el mismo que el del servidor
Hacer el trabajo del viernes
Ejecutado a través del programa Como resultado, podemos encontrar que se genera un objeto de enumeración tanto en la máquina virtual del cliente como en la del servidor en condiciones distribuidas, incluso si el valor de enumeración Fri parece el mismo, si se usa el signo igual '==' para comparar. , habrá diferencias, etc. La declaración de cambio utiliza el método igual para comparar los valores de los objetos de enumeración. Por lo tanto, cuando su objeto de enumeración es complejo, debe tener cuidado con los métodos anulados y relacionados con la comparación para evitar errores en la comparación de valores.
Clases de herramientas relacionadas con Enum
En JDK5.0, al agregar la clase Enum, también agregó dos clases de herramientas, EnumSet y EnumMap, las cuales se colocan en java.util. Cierto. EnumSet es una implementación de interfaz Set de alto rendimiento para tipos de enumeración. Todos los objetos de enumeración cargados en EnumSet deben ser del mismo tipo. Internamente, se implementan mediante vector de bits, es decir, mediante un número de tipo largo. EnumSet admite la iteración en un rango de todos los valores del tipo de enumeración. Volver al ejemplo de enumeración de fechas anterior: enum?WeekDayEnum?{?Mon,?Tue,?Wed,?Thu,?Fri,?Sat,?Sun?}
Puede iterar a través de fechas, La clase EnumSet proporciona un rango de métodos estáticos para facilitar la iteración: for(WeekDayEnum?day?:?EnumSet.range(WeekDayEnum.Mon,?WeekDayEnum.Fri))?{? System.out.println(day );? p>
El resultado de la impresión es el siguiente: ¿lunes? ¿martes? el subconjunto: EnumSetlt; WeekDayEnumgt;?subset?=?EnumSet.of(WeekDayEnum.Mon,?WeekDayEnum.Wed);? para?(WeekDayEnum?day?:?subset)?{? }
El resultado de la impresión es el siguiente: lun? mié
Similar a EnumSet, EnumMap también es una implementación de interfaz Map de alto rendimiento, que se utiliza para gestionar el mapeo utilizando tipos de enumeración como claves. Las tablas se implementan internamente a través de matrices. EnumMap combina la interfaz Map rica y segura con un acceso rápido a la matriz. Si desea asignar un tipo de enumeración a un valor, debe usar EnumMap.
Mire el siguiente ejemplo:
Listado 5. Ejemplo de EnumMap // Definir un objeto EnumMap La clave principal de la tabla de mapeo es el tipo de enumeración de fecha y el valor es el tipo de enumeración de color ¿privado? Maplt; WeekDayEnum, ?RainbowColorgt;?schema?=?
new?EnumMaplt;WeekDayEnum,?RainbowColorgt;(WeekDayEnum.class);?static{?
//?Convertir cada uno día de la semana para mapear un determinado color del arco iris
for?(int?i?=?0;?i?lt;?WeekDayEnum.values().length;?i )?{?
schema.put(WeekDayEnum.values()[i],?RainbowColor.values()[i]);?
}? System.out.println(" ¿Cuál?es?el?color?de?la?suerte???");? System.out.println("¿Es?"? ?schema.get(WeekDayEnum.Sat));
Cuando preguntas por el color del sábado color de la suerte, obtendrás azul:
Listado 6. Resultados de ejecución
¿Cuál es el color de la suerte hoy?
Es AZUL
Conclusión
El tipo Enum aporta una gran comodidad a la programación JAVA, haciendo que el control del programa sea más fácil y menos propenso a errores. Entonces, cuando necesites controlar el flujo del programa, puedes pensar más en si puedes usar enum para lograrlo.