Cuando comenzaba a programar en Java, el hecho de que las declaraciones de cambio no tomaran cadenas me frustraba. Luego, al usar Enums, me di cuenta de los beneficios que obtienes con ellos en lugar de pasar valores en bruto: seguridad de tipo (que brinda una refactorización más fácil) y también claridad para otros desarrolladores.
Me cuesta pensar en una situación en la que con SE7 ahora decidiré usar un interruptor con cadenas como entradas en lugar de Enums. Si se implementan activando cadenas enteras (por ejemplo, en lugar de coincidencias parciales o expresiones regulares), no parece ofrecer menos razones para que el código cambie.
Y con las herramientas IDE y la relación de lectura y escritura de la codificación, sería mucho más feliz generar automáticamente una enumeración adicional que pasar valores de cadena.
¿Qué beneficio nos aportan como programadores? ¿Menos placa de caldera?
No parece que el idioma estuviera pidiendo esta característica. Aunque tal vez hay un caso de uso que estoy pasando por alto.
fuente
Respuestas:
Por lo que puedo decir, la pregunta es por qué envolver las constantes de String en enum no se ha considerado suficiente para cubrir las necesidades de los usuarios del lenguaje. Esto se ha abordado en la propuesta de función oficial anunciada en la lista de correo JDK 7 (proyecto de moneda).
Según mi lectura de la propuesta, se ha descartado la alternativa de usar enumeraciones debido a que introduce tipos de hinchazón. Para su conveniencia, la parte relevante de la propuesta se cita a continuación, con la declaración que aborda las enumeraciones en negrita :
fuente
Además de hacer que el código sea más legible, hay posibles ganancias de rendimiento en relación con las
if/else if
comparaciones. Si el cambio vale la pena depende de cuántas comparaciones estaría haciendo. Se emitirá un interruptor de cadena como dos instrucciones de interruptor separadas. El primero opera con códigos hash, por lo que tiende a ser una complejidadlookupswitch
que finalmente generaO(log n)
. El segundo siempre es perfectoO(1)
tableswitch
, por lo que la complejidad combinada sigue siendoO(log n)
. Una sola cadena lineal deif/else if
declaraciones daría unaO(n)
complejidad ligeramente peor .Si está comparando más de, digamos, tres cadenas, entonces a
switch
es probablemente más legible y compacto. Es probable que funcione mejor, aunque es poco probable que note una diferencia a menos que esté haciendo una gran cantidad de comparaciones en una ruta de código dinámico.fuente
if/else
mala práctica de un bloque grande , pero por el momento, no tendría muchas razones para usar una.El cambio de cadenas podría usarse cuando sus
enum
valores provienen del exterior, es decir, almacenados en una base de datos.Otra cosa notable en JDK 7
switch
es que es mucho más perfumante que lasif-else
construcciones.Y un buen caso de uso para cadenas rápidas
switch
podría ser el análisis de flujo JSON / XML cuando necesita hacer muchos cambios en los tipos de nodo y atributo. No puedo pensar en una mejor opción para esto.fuente
enum
se pueden usar s en este caso debido a la naturaleza estática de Java. Cuando estaba escribiendo esto, estaba pensando en unaRole
de una biblioteca de seguridad que generalmente se proporciona como una clase y no se puede incluirenum
. Otro caso es un código Java / Groovy compilado dinámicamente; en esta situación, que es rara, los conmutadores de cadena podrían ser una mejor opción.Sencillez
La compatibilidad con String in Switch es útil para procesar datos sin conversión a enumeración o
if-else
lógica. A veces es más fácil activar String.De la propuesta de características en la lista de correo JDK 7 (proyecto Coin) ( @gnat answer )
Versión If-Else
Esto es corto, pero muchos
if's
son difíciles de leer. Y esto es lento.Versión Enum
Las enumeraciones deben definirse, esto es bueno, pero a veces no es necesario.
Procesando como siempre
JDK 7: cadenas en la versión de declaraciones de conmutador
Podemos procesar sin convertir y definir tipos adicionales.
fuente
La mayoría de las mejoras en cualquier idioma son para hacer que el código sea más fácil de leer. Estoy a favor del código legible sobre el elegante cualquier día.
Puede que no lo creas, pero prueba:
fuente
Las enumeraciones son geniales y debe usarlas en lugar de cadenas cuando tenga la capacidad de hacerlo. Pero hay algunas ocasiones en las que simplemente no puede, por ejemplo, cuando necesita trabajar con algún objeto externo que proviene de fuera de Java. Imagina que tienes que analizar algo. Al igual que la respuesta del servidor, la configuración, el archivo de registro o algo similar: tiene un montón de opciones que está buscando y no hay forma de que puedan ser enumeraciones. Entonces en Java <7 estarías atrapado con un montón de
Todavía puede usar enumeraciones en este caso simplemente tratando de obtenerlas por nombres y / o proporcionando una cadena personalizada-> rutina de enumeración, pero a veces no es posible o simplemente no es práctico (es decir, cuando tendría que crear demasiadas enumeraciones)
TLDR : absolutamente debe usar Enums cuando trabaja puramente con código Java, pero no siempre es posible con objetos externos. Espero que mi explicación tenga sentido.
fuente
if
declaraciones, entonces debería estar resumiendo de todos modos , lo que significa que aún podría usar enumeraciones o un patrón de comando, etc.No estoy de acuerdo con la opinión de que es un código más limpio y legible cuando lo usas
Strings
en declaraciones de cambio y piensas que es una mala práctica de programación. Si cambia el valor que usa para almacenar, tiene que cambiarlo cada vez que cambie o si ocurre. Esto no es bueno ya que está poniendo valores codificados en cada bir de su código. ¿Qué vas a hacer si algún día decides cambiar uno de estos valores codificados? ¿Buscar y reemplazar cada copia?Si tiene algunos valores codificados que hace declaraciones if-elseif, usar valores primitivos constantes para ellos es mucho mejor antes de Java 1.5 solo porque brinda seguridad de tipo.
OK, habrá situaciones en las que obtendrás valores de cadena (de solicitud HTTP, archivos, etc.) y convertirlos a los valores primitivos es muy doloroso. Pero
Enum
hacemos un buen trabajo en este punto. Porque cuando desee cambiar el valor que almacena en Enum, simplemente cámbielo cuando declare. No hay necesidad de cambiar nada más en su código. (Por supuesto, debe cambiar los valores almacenados en otro lugar).Por supuesto, si solo está implementando un código sucio y vago, es perfecto. No desea involucrar codificar muchos
Enum
s, pero en un software complejo a gran escala que lo matará.fuente
Si sabe qué información ingresa y que solo puede ser de 5 estados, utilice un
Enum
. Sin embargo, si los posibles estados podrían ser superiores a 9000 y solo necesita encontrar 42, entonces usar un interruptor es mejor porque no desea escribir todos esos estados.Un Enum tiende a ser la elección de la mayoría en la mayoría de las circunstancias, a menos que los posibles estados sean desconocidos o haya muchos y solo le importen unos pocos.
¿Pero por qué lo presentaron ahora? Fue solo un cambio que permitió un código más limpio.
En 1.5 también le permitieron crear cuerpos personalizados para Enums.
fuente
default
enswitch
viene a jugar. No sé si puede tener un estado predeterminadoEnum
, a menos que establezca un estado predeterminado, pero luego este código simplemente se hincha, mientras que aswitch
es mucho más limpio de usar.UNKNOWN
estado en un Enum es hinchado, pero undefault
caso en un interruptor no lo es.