## Sentencias de Control de Flujo

Las sentencias de control de flujo determinan el orden en que se ejecutarán las otras sentencias dentro del programa. El lenguaje Java soporta varias sentencias de control de flujo, incluyendo:

Sentencias | palabras clave
toma de decisiones | if-else, switch-case
bucles | for, while, do-while
excepciones | try-catch-finally, throw
miscelaneas | break, continue, label:, return

Nota: Aunque goto es una palabra reservada, actualmente el lenguaje Java no la soporta. Podemos utilizar las rupturas etiquetadas en su lugar.

#### La sentencia if-else

> La sentencia if-else de java proporciona a los programas la posibilidad de ejecutar selectivamente otras sentencias basándose en algún criterio. Por ejemplo, supon que tu programa imprime información de depurado basándose en el valor de una variable booleana llamada DEBUG. Si DEBUG fuera verdadera true, el programa imprimiría la información de depurado, como por ejemplo, el valor de una variable como x. Si DEBUG es false el programa procederá normalmente. Un segmento de código que implemente esto se podría parecer a este:

>     . . .
>     if (DEBUG)
>         System.out.println("DEBUG: x = " + x);
>     . . .

> Esta es la versión más sencilla de la sentencia if: la sentencia gobernada por if se ejecuta si alguna codición es verdadera. Generalmente, la forma sencilla de if se puede escribir así:

>     if (expresión)
>         sentencia

> Pero, ży si quieres ejecutar un juego diferente de sentencias si la expresión es falsa? Bien, puedes utilizar la sentencia else. Echemos un vistazo a otro ejemplo. Supon que tu programa necesita realizar diferentes acciones dependiendo de que el usuario pulse el botón OK o el botón Cancel en un ventana de alarma. Se podría hacer esto utilizando una sentencia if:

>         . . .
>         // Respuesta dependiente del botoón que haya pulsado el usuario
>         // OK o Cancel
>         . . .
>     if (respuesta == OK) {
>         . . .
>         // Código para la acción OK
>         . . .
>     } else {
>         . . .
>         // código para la acción Cancel
>         . . .
>     }

> Este uso particular de la sentencia else es la forma de capturarlo todo. Existe otra forma de la sentecia else, else if que ejecuta una sentencia basada en otra expresión. Por ejemplo, supon que has escrito un programa que asigna notas basadas en la puntuación de un examen, un Sobresaliente para una puntuación del 90% o superior, un Notable para el 80% o superior y demás. odrías utilizar una sentencia if con una serie de comparaciones else if y una setencia else para escribir este código:

>     int puntuacion;
>     String nota;

>     if (puntuacion >= 90) {
>         nota = "Sobresaliente";
>     } else if (puntuacion >= 80) {
>         nota = "Notable";
>     } else if (puntuacion >= 70) {
>         nota = "Bien";
>     } else if (puntuacion >= 60) {
>         nota = "Suficiente";
>     } else {
>         nota = "Insuficiente";
>     }

> Una sentencia if puede tener cualquier número de sentencias de acompañamiento else if. Podrías haber observado que algunos valores de puntuacion pueden satisfacer más una de las expresiones que componen la sentencia if. Por ejemplo, una puntuación de 76 podría evaluarse como true para dos expresiones de esta sentencia:puntuacion >= 70 y puntuacion >= 60. Sin embargo, en el momento de ejecución, el sistema procesa una sentencia if compuesta como una sóla; una vez que se ha satisfecho una condición (76 >= 70), se ejecuta la sentencia apropiada (nota = "Bien";), y el control sale fuera de la sentencia if sin evaluar las condiciones restantes.

#### La sentencia switch

> La sentencia switch se utiliza para realizar sentencias condicionalmente basadas en alguna expresión. Por ejemplo, supon que tu programa contiene un entero llamado mes cuyo valor indica el mes en alguna fecha. Supon que también quieres mostrar el nombre del mes basándose en su número entero equivalente. Podrías utilizar la sentencia switch de Java para realizar esta tarea:

>     int mes;
>     . . .
>     switch (mes) {
>     case 1:  System.out.println("Enero"); break;
>     case 2:  System.out.println("Febrero"); break;
>     case 3:  System.out.println("Marzo"); break;
>     case 4:  System.out.println("Abril"); break;
>     case 5:  System.out.println("May0"); break;
>     case 6:  System.out.println("Junio"); break;
>     case 7:  System.out.println("Julio"); break;
>     case 8:  System.out.println("Agosto"); break;
>     case 9:  System.out.println("Septiembre"); break;
>     case 10: System.out.println("Octubre"); break;
>     case 11: System.out.println("Noviembre"); break;
>     case 12: System.out.println("Diciembre"); break;
>     }

> La sentencia switch evalúa su expresión, en este caso el valor de mes, y ejecuta la sentencia case apropiada. Decidir cuando utilizar las sentencias if o switch dependen del juicio personal. Puedes decidir cual utilizar basándose en la buena lectura del código o en otros factores.

> Cada sentencia case debe ser única y el valor proporcionado a cada sentencia case debe ser del mismo tipo que el tipo de dato devuelto por la expresión proporcionada a la sentencia switch.

> Otro punto de interes en la sentencia switch son las sentencias break después de cada case. La sentencia break hace que el control salga de la sentencia switch y continúe con la siguiente línea. La sentencia break es necesaria porque las sentencias case se siguen ejecutando hacia abajo. Esto es, sin un break explícito, el flujo de control seguiría secuencialmente a través de las sentencias case siguientes. En el ejemplo anterior, no se quiere que el flujo vaya de una sentencia case a otra, por eso se han tenido que poner las sentencias break. Sin embargo, hay ciertos escenario en los que querrás que el control proceda secuencialmente a través de las sentencias case. Como este código que calcula el número de días de un mes de acuerdo con el ritmico refrán que dice "Treinta tiene Septiembre...".

>     int mes;
>     int numeroDias;
>     . . .
>     switch (mes) {
>     case 1:
>     case 3:
>     case 5:
>     case 7:
>     case 8:
>     case 10:
>     case 12:
>         numeroDias = 31;
>         break;
>     case 4:
>     case 6:
>     case 9:
>     case 11:
>         numeroDias = 30;
>         break;
>     case 2:
>         if ( ((ano % 4 == 0) && !(ano % 100 == 0)) || ano % 400 == 0) )
>             numeroDias = 29;
>         else
>             numeroDias = 28;
>         break;
>     }

Finalmente, puede utilizar la sentencia default al final de la sentencia switch para manejar los valores que no se han manejado explícitamente por una de las sentencias case.

    int mes;
    . . .
    switch (mes) {
    case 1:  System.out.println("Enero"); break;
    case 2:  System.out.println("Febrero"); break;
    case 3:  System.out.println("Marzo"); break;
    case 4:  System.out.println("Abril"); break;
    case 5:  System.out.println("Mayo"); break;
    case 6:  System.out.println("Junio"); break;
    case 7:  System.out.println("Julio"); break;
    case 8:  System.out.println("Agosto"); break;
    case 9:  System.out.println("Septiembre"); break;
    case 10: System.out.println("Octubre"); break;
    case 11: System.out.println("Noviembre"); break;
    case 12: System.out.println("Diciembre"); break;
    default: System.out.println("Ee, no es un mes válido!");
        break;
    }

#### Sentencias de Bucle

> Generalmente hablando, una sentencia while realiza una acción mientras se cumpla una cierta condición. La sintaxis general de la sentencia while es:

>     while (expresión)
>         sentencia

> Esto es, mientras la expresión sea verdadera, ejecutará la sentencia.

> sentencia puede ser una sóla sentencia o puede ser un bloque de sentencias. Un bloque de sentencias es un juego de sentencias legales de java contenidas dentro de corchetes('{'y '}'). Por ejemplo, supon que además de incrementar contador dentro de un bucle while también quieres imprimir el contador cada vez que se lea un carácter. Podrías escribir esto en su lugar:

>     . . .
>     while (System.in.read() != -1) {
>         contador++;
>         System.out.println("Se ha leido un el carácter = " + contador);
>     }
>     . . .

> Por convención el corchete abierto '{' se coloca al final de la misma línea donde se encuentra la sentencia while y el corchete cerrado '}' empieza una nueva línea indentada a la línea en la que se encuentra el while.

> Además de while Java tiene otros dos constructores de bucles que puedes utilizar en tus programas: el bucle for y el bucle do-while.

> Primero el bucle for. Puedes utilizar este bucle cuando conozcas los límites del bucle (su instrucción de inicialización, su criterio de terminación y su instrucción de incremento). Por ejemplo, el bucle for se utiliza frecuentemente para iterar sobre los elementos de un array, o los caracteres de una cadena.

>     // a es un array de cualquier tipo
>     . . .
>     int i;
>     int length = a.length;
>     for (i = 0; i < length; i++) {
>         . . .
>         // hace algo en el elemento i del array a
>         . . .
>     }

> Si sabes cuando estas escribiendo el programa que quieres empezar en el inicio del array, parar al final y utilizar cada uno de los elementos. Entonces la sentencia for es una buena elección. La forma general del bucle for puede expresarse asi:

>     for (inicialización; terminación; incremento)
>         sentencias

> inicialización es la sentencia que inicializa el bucle -- se ejecuta una vez al iniciar el bucle.
> terminación es una sentecia que determina cuando se termina el bucle. Esta expresión se evalúa al principio de cada iteracción en el bucle. Cuando la expreión se evalúa a false el bucle se termina.
> Finalmente, incremento es una expresión que se invoca en cada interacción del bucle. Cualquiera (o todos) de estos componentes puden ser una sentencia vacía (un punto y coma).

> Java proporciona otro bucle, el bucle do-while,que es similar al bucle while que se vió al principio, excepto en que la expresión se avalú al final del bucle:

>     do {
>         sentencias
>     } while (Expresión Booleana);

> La sentencia do-while se usa muy poco en la construcción de bucles pero tiene sus usos. Por ejemplo, es conveniente utilizar la sentencia do-while cuando el bucle debe ejecutarse al menos una vez. Por ejemplo, para leer información de un fichero, sabemos que al menos debe leer un carácter:

>     int c;
>     InputStream in;
>     . . .
>     do {
>         c = in.read();
>         . . .
>     } while (c != -1);

#### Sentencias de Manejo de Excepciones

> Cuando ocurre un error dentro de un método Java, el método puede lanzar una excepción para indicar a su llamador que ha ocurrido un error y que el error está utilizando la sentencia throw. El método llamador puede utilizar las sentencias try, catch, y finally para capturar y manejar la excepción. Puedes ver Manejar Errores Utilizando Excepciones para obtener más información sobre el lanzamiento y manejo de excepciones.

#### Sentencias de Ruptura

> Ya has visto la sentencia break en acción dentro de la sentencia switch anteriormente. Como se observó anteriormente, la sentencia break hace que el control del flujo salte a la sentencia siguiente a la actual.

> Hay otra forma de break que hace que el flujo de control salte a una sentencia etiquetada. Se puede etiquetar una sentencia utilizando un identificador legal de Java (la etiqueta) seguido por dos puntos (:) antes de la sentencia:

>     SaltaAqui: algunaSentenciaJava

> Para saltar a la sentencia etiquetada utilice esta forma de la sentencia break.

>     break SaltaAqui;

> Las rupturas etiquetadas son una alternativa a la sentencia goto que no está soportada por el lenguaje Java.

> Se puede utiliza la sentencia continue dentro de un bucle para saltar de la sentencia actual hacia el principio del bucle o a una sentencia etiquetada. Considera esta implementación del método indexOf() de la clase String que utiliza la forma de continue que continúa en una sentencia etiquetada:

>     public int indexOf(String str, int fromIndex) {
>         char[] v1 = value;
>         char[] v2 = str.value;
>         int max = offset + (count - str.count);
>       test:
>         for (int i = offset + ((fromIndex < 0) ? 0 : fromIndex); i <= max ; i++) {
>             int n = str.count;
>             int j = i;
>             int k = str.offset;
>             while (n-- != 0) {
>                 if (v1[j++] != v2[k++]) {
>                     continue test;
>                 }
>             }
>             return i - offset;
>         }
>         return -1;
>     }

> Nota: Sólo se puede llamar a la sentencia continue desde dentro de un bucle.

> Y finalmente la sentencia return. Esta sentencia se utiliza para salir del método actual y volver a la sentencia siguiente a la que originó la llamada en el método original. Existen dos formas de return: una que devuelve un valor y otra que no lo hace. Para devolver un valor, simplemente se pone el valor (o una expresión que calcule el valor) detrás de la palabra return:

>     return ++count;

> El valor devuelto por return debe corresponder con el tipo del valor de retorno de la declaración del método.

> Cuando un método se declara como void utiliza la forma de return que no devuelve ningún valor:

>     return;

Ozito