tutorial ejemplo java switch-statement case language-design break

ejemplo - text box java



¿Por qué necesitamos declaraciones de break after case? (16)

¿Por qué el compilador no pone declaraciones de interrupción automáticamente después de cada bloque de código en el conmutador?

Dejando de lado el buen deseo de poder usar el bloque idéntico para varios casos (que podría ser de carcasa especial) ...

¿Es por razones históricas? ¿Cuándo quieres que se ejecuten varios bloques de código?

Se debe principalmente a la compatibilidad con C, y podría decirse que es un antiguo truco de los viejos tiempos cuando las palabras clave goto recorrían la tierra. Por supuesto, permite algunas cosas sorprendentes, como el dispositivo de Duff , pero si ese es un punto a favor o en contra es ... argumentativo en el mejor de los casos.

¿Por qué el compilador no pone declaraciones de interrupción automáticamente después de cada bloque de código en el conmutador? ¿Es por razones históricas? ¿Cuándo quieres que se ejecuten varios bloques de código?


A veces es útil tener múltiples casos asociados con el mismo bloque de código, como

case ''A'': case ''B'': case ''C'': doSomething(); break; case ''D'': case ''E'': doSomethingElse(); break;

etc. Solo un ejemplo.

En mi experiencia, por lo general, es un mal estilo "fallido" y se ejecutan múltiples bloques de código para un caso, pero puede haber usos para él en algunas situaciones.


Ahora estoy trabajando en un proyecto en el que necesito una break en mi declaración de cambio, de lo contrario, el código no funcionará. Desnúdate conmigo y te daré un buen ejemplo de por qué necesitas break tu declaración de cambio.

Imagine que tiene tres estados, uno que espera que el usuario ingrese un número, el segundo para calcularlo y el tercero para imprimir la suma.

En ese caso, tienes:

  1. State1 - Espera a que el usuario ingrese un número
  2. State2 - Imprime la suma
  3. state3 - Calcula la suma

En cuanto a los estados, querría que el orden de exacción comenzara en state1 , luego state3 y finalmente state2 . De lo contrario, solo imprimiremos la entrada de los usuarios sin calcular la suma. Solo para aclararlo de nuevo, esperamos que el usuario ingrese un valor, luego calcula la suma e imprime la suma.

Aquí hay un código de ejemplo:

while(1){ switch(state){ case state1: // Wait for user input code state = state3; // Jump to state3 break; case state2: //Print the sum code state = state3; // Jump to state3; case state3: // Calculate the sum code state = wait; // Jump to state1 break; } }

Si no usamos break , se ejecutará en este orden, state1 , state2 y state3 . Pero al usar el break , evitamos este escenario y podemos ordenar el procedimiento correcto que debe comenzar con state1, luego state3 y last but not least state2.


Al no tener un corte automático agregado por el compilador, es posible usar un interruptor / caja para probar condiciones como 1 <= a <= 3 eliminando la declaración de corte de 1 y 2.

switch(a) { case 1: //I''m between 1 and 3 case 2: //I''m between 1 and 3 case 3: //I''m between 1 and 3 break; }


Como decía la gente antes, es para permitir la caída y no es un error, es una característica. Si demasiadas declaraciones de break molestan, puede deshacerse de ellos fácilmente mediante el uso de declaraciones de return lugar. Esto es realmente una buena práctica, porque sus métodos deben ser lo más pequeños posible (por razones de legibilidad y mantenibilidad), por lo que una instrucción switch ya es lo suficientemente grande para un método, por lo tanto, un buen método no debe contener nada más, esto es un ejemplo:

public class SwitchTester{ private static final Log log = LogFactory.getLog(SwitchTester.class); public static void main(String[] args){ log.info(monthsOfTheSeason(Season.WINTER)); log.info(monthsOfTheSeason(Season.SPRING)); log.info(monthsOfTheSeason(Season.SUMMER)); log.info(monthsOfTheSeason(Season.AUTUMN)); } enum Season{WINTER, SPRING, SUMMER, AUTUMN}; static String monthsOfTheSeason(Season season){ switch(season){ case WINTER: return "Dec, Jan, Feb"; case SPRING: return "Mar, Apr, May"; case SUMMER: return "Jun, Jul, Aug"; case AUTUMN: return "Sep, Oct, Nov"; default: //actually a NullPointerException will be thrown before reaching this throw new IllegalArgumentException("Season must not be null"); } } }

La ejecución imprime:

12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb 12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May 12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug 12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov

como se esperaba.


Creo que es un error Como una construcción de lenguaje, es tan fácil tener la break como el valor predeterminado y, en cambio, tener una palabra clave fallthrough . La mayoría del código que he escrito y leído tiene un descanso después de cada caso.


En cuanto al registro histórico, Tony Hoare inventó la declaración de caso en la década de 1960, durante la revolución de la "programación estructurada". La declaración del caso de Tony admitía múltiples etiquetas por caso y salida automática sin declaraciones de hediondo. El requisito de un break explícito fue algo que salió de la línea BCPL / B / C. Dennis Ritchie escribe (en ACM HOPL-II):

Por ejemplo, el endcase que escapa de una declaración switchon BCPL no estaba presente en el lenguaje cuando lo aprendimos en la década de 1960, por lo que la sobrecarga de la palabra clave break para escapar de la instrucción switch B y C se debe a evolución divergente más que consciente cambio.

No he podido encontrar ningún escrito histórico sobre BCPL, pero el comentario de Ritchie sugiere que la break fue más o menos un accidente histórico. Posteriormente, BCPL resolvió el problema, pero tal vez Ritchie y Thompson estaban demasiado ocupados inventando Unix como para molestarse con tal detalle :-)


Es una vieja pregunta, pero en realidad me topé con el uso del caso sin declaración de interrupción hoy. No usar break es realmente muy útil cuando necesitas combinar diferentes funciones en secuencia.

por ejemplo, usando códigos de respuesta http para autenticar usuario con token de tiempo

código de respuesta del servidor 401 - el token no está actualizado -> regenerar el token y registrar al usuario.
Código de respuesta del servidor 200 - El token está OK -> Ingresar usuario en.

en caso declaraciones:

case 404: case 500: { Log.v("Server responses","Unable to respond due to server error"); break; } case 401: { //regenerate token } case 200: { // log in user break; }

Al utilizar esto, no es necesario llamar a la función de usuario de inicio de sesión para la respuesta 401 porque cuando se regenera el token, el tiempo de ejecución salta al caso 200.


Exactamente, porque con una ubicación inteligente puedes ejecutar bloques en cascada.


Java proviene de C y esa es la sintaxis de C.

Hay momentos en los que quiere que múltiples declaraciones de casos solo tengan una ruta de ejecución. A continuación hay una muestra que le indicará cuántos días en un mes.

class SwitchDemo2 { public static void main(String[] args) { int month = 2; int year = 2000; int numDays = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31; break; case 4: case 6: case 9: case 11: numDays = 30; break; case 2: if ( ((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0) ) numDays = 29; else numDays = 28; break; default: System.out.println("Invalid month."); break; } System.out.println("Number of Days = " + numDays); } }


Java se deriva de C, cuyo patrimonio incluye una técnica conocida como Dispositivo de Duff . Es una optimización que se basa en el hecho de que el control pasa de un caso a otro sin break; declaración. Para cuando C estaba estandarizado, había muchos códigos como ese "en la naturaleza", y hubiera sido contraproducente cambiar el lenguaje para romper tales construcciones.


Por lo tanto, no tiene que repetir el código si necesita varios casos para hacer lo mismo:

case THIS: case THAT: { code; break; }

O puedes hacer cosas como:

case THIS: { do this; } case THAT: { do that; }

En forma de cascada.

Realmente propenso a errores / confusión, si me preguntas.


Puede hacer fácilmente separar otro tipo de número, mes, recuento.
Esto es mejor que si en este caso;

public static void spanishNumbers(String span){ span = span.toLowerCase().replace(" ", ""); switch (span){ case "1": case "jan": System.out.println("uno"); break; case "2": case "feb": System.out.println("dos"); break; case "3": case "mar": System.out.println("tres"); break; case "4": case "apr": System.out.println("cuatro"); break; case "5": case "may": System.out.println("cinco"); break; case "6": case "jun": System.out.println("seis"); break; case "7": case "jul": System.out.println("seite"); break; case "8": case "aug": System.out.println("ocho"); break; case "9": case "sep": System.out.println("nueve"); break; case "10": case "oct": System.out.println("diez"); break; } }


Puedes hacer todo tipo de cosas interesantes con el fracaso del caso.

Por ejemplo, digamos que desea realizar una acción en particular para todos los casos, pero en determinado caso desea hacer esa acción más otra cosa. Usar una instrucción switch con fall-down lo haría bastante fácil.

switch (someValue) { case extendedActionValue: // do extended action here, falls through to normal action case normalActionValue: case otherNormalActionValue: // do normal action here break; }

Por supuesto, es fácil olvidar la declaración de break al final de un caso y provocar un comportamiento inesperado. Los buenos compiladores lo advertirán cuando omita la declaración de interrupción.


porque hay situaciones en las que desea pasar por el primer bloque, por ejemplo, para evitar escribir el mismo código en varios bloques, pero aún así poder dividirlos para el control de mroe. También hay muchas otras razones.


Historically , es porque el case esencialmente definía una label , también conocida como el punto objetivo de una llamada goto . La instrucción switch y sus casos asociados realmente solo representan una rama multivía con múltiples puntos de entrada potenciales en una secuencia de código.

Dicho todo esto, se ha observado un número casi infinito de veces que la break es casi siempre el comportamiento predeterminado que preferirías tener al final de cada caso.