Control de Flujo en JAVA

Ejecutan un código u otro en función de que se cumplan o no una determinada condición.
Pasemos a ver sus principales tipos.

If then Else
Su modo más simple de empleo es:

If(condicion) {
Grupo de sentencias}

Condición es una valor tipo boolean. El grupo de sentencias se ejecuta solo si la condición toma un valor true. En caso contrario se sigue ejecutando ignorando el Grupo de sentencias.

If(condicion) {
Grupo de sentencias}
else{
Grupo2 de sentencias}

Si condición toma el valor true se ejecuta Grupo de sentencias, en caso contrario se ejecuta Grupo2 de sentencias. En ambos casos se continúa ejecutando el resto del código.

If(condicion) {
Grupo de sentencias}

else if (condicion2){
"valor: " + (int)c +
" caracter: " + c);
}
} ///:~

Grupo2 de sentencias}
else if (condicion3){
Grupo3 de sentencias}

else{
Grupo_n de sentencias}

Si condición toma el valor true se ejecuta Grupo de sentencias, si condicion2 toma el valor true se ejecuta Grupo2 de sentencias... y así sucesivamente hasta acabarse todas las condiciones.
Si no se cumple ninguna se ejecuta Grupo_n de sentencias. Este último else es opcional. En ambos casos se continúa ejecutando el resto del código.

Ilustraremos esto con el siguiente ejemplo:

Switch
Los creadores de Java trataron de hacer de este lenguaje una versión simplificada y mejorada del lenguaje de C++. Su trabajo fue bastante bueno, pero no perfecto. Prueba de ello es esta sentencia: está tan poco flexible como en C++.

Expliquemos su sintaxis antes de dar los motivos de esta crítica:
switch(selector) {
case valor1 : Grupo de sentencias1; break;
case valor2 : Grupo de sentencias2; break;
case valor3 : Grupo de sentencias3; break;
case valor4 : Grupo de sentencias4; break;
case valor5 : Grupo de sentencias5; break;
// ...
default: statement;
}

Se compara el valor de selector con sentencias_n. Si el valor coincide se ejecuta su respectivo grupo de secuencias. Si no se encuentra ninguna coincidencia se ejecutan las sentencias de default. Si no se pusieran los break una vez que se encontrase un valor que coincida con el selector se ejecutarían todos los grupos de sentencias, incluída la del default.
Ha llegado el momento de justificar la crítica hecha a los creadores de Java. Este tipo de estructura tiene sus posibilidades muy limitadas, ya que en las condiciones sólo se admite la igualdad, no ningún otro tipo de condición (sería fácil pensar ejemplos dónde, por poner un caso, se le sacaría partido a esta sentencia si aceptase desigualdades). Además para colmo esta comparación de igualdad sólo admite valores tipo char o cualquier tipo de valores enteros menos long. No podemos comparar contra reales, strings....
También se le podría criticar el hecho de que una vez cumplidas una condición se ejecuten todas las sentencias si no hay instrucciones break que lo impidan. Esto es en muchas ocasiones fuente de errores, aunque también hay que reconocer que a veces se le puede sacar partido, de hecho en el ejemplo que empleamos para ilustrar esta sentencia aprovechamos esta característica:

public class ejemplo8 {
public static void main(String[] args) {
//Bucle for. Ejecutará 100 veces el código que tiene dentro.
for(int i = 0; i < 100; i++) {
//Math.random() es un métod estático que genra un número real
//aleatorio entre 0 y 1.
//Math.random()*26 será un número real aleatorio entre 0 y
//26. Al sumarle un carácter, ‘a’ el carácter se transforma a
//un enteroy se le suma. ‘a’ = 97.
//Se transforma el número aleatorio entre 97y 97 + 26 en el
//carácter correspodiente a su parte entera. Será un carácter
//aleatorio, que por la disposición de los caracteres Unicode
//será un letra del abecedario.
char c = (char)(Math.random() * 26 + 'a');
System.out.print(c + ": ");
switch(c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
//Si el carácter es ‘a’, ‘e’, ‘i’, ‘o’ o ‘u’ imprimimos
//vocal.
System.out.println("vocal");
break;
default:
//Si no era ninguna de las anterioes imprimos consonate.
System.out.println("consonante");
}
}
}
} ///:~

BUCLES
Son instrucciones que nos permiten repetir un bloque de código mientras se cumpla una determinada condición. Pasemos a ver sus tipos.

Bucle while
Cuando en la ejecución de un código se llega a un bucle while se comprueba si se verifica su condición, si se verifica se continua ejecutando el código del bucle hasta que esta deje de verificarse. Su sintaxis es:

while(condición){
Grupo de sentencias}

Ilustramos su funcionamiento con un ejemplo:

public class ejemplo9 {
public static void main(String[] args) {
double r = 0;
//Mientras que r < 0.99 sigue ejecutando el cuerpo del bucle.
//La d significa double. No es necesaria
while(r < 0.99d) {
//Genera un nuevo r aleatario entr 0 y 1.
r = Math.random();
//Lo imprime por consola.
System.out.println(r);
}
}
} ///:~

Bucle do while
 Su comportamiento es semejante al bucle while, sólo que aquí la condición va al final del código del bucle, por lo que tenemos garantizado que el código se va a ejecutar al menos una vez. Dependerá del caso concreto si es más conveniente emplear un bucle while o do while. La sintaxis de do while es:

do {
Grupo de sentencias;
}while(condición);

 Obsérvese como el ejemplo 9 implementado mediante un bucle do while independientemente del valor de r ejecutará al menos una vez el código de su cuerpo:

public static void main(String[] args) {
double r;
//Idéntico al ejemplo anterior, solo que aahora la condición
//está al final del bucle.
do {
r = Math.random();
System.out.println(r);
} while(r < 0.99d);
}
} ///:~
public class ejemplo10 {

Bucle for
Su formato es el siguiente:

for(expresion1;expresion2;expresion3){
Grupo de sentecias;}

Expresion1 es una asignación de un valor a una variable, la variable-condición del bucle.
Expresion2 es la condición que se le impone a la variable del bucle y expresion3 indica una operación que se realiza en cada iteración a partir de la primera (en la primera iteración el valor de la variable del bucle es el que se le asigna en expresion1) sobre la variable del bucle.

public class ejemplo11 {
public static void main(String[] args) {
for( char c = 0; c < 128; c++)
//Imprime los caracteres correspondientes a los números
//enteros comprendidos entre 0 y 128. (int)c es el entero
//correspondiente al carácter c.

System.out.println(
public class ejemplo12 {
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
if(i == 74) break; // teminamos aqui el bucle
//Salto a la siguiente iteración si i no es divisible entre 9
if(i % 9 != 0) continue;
//Si I es divisible entre 9 se imprime
System.out.println(i);
}
int i = 0;
// Lazo infinito del cual se sale con break:
while(true) {
i++;
int j = i * 27;
if(j == 1269) break; // Salimos del lazo
if(i%10 != 0) continue;//Salto a la siguiente iteración
System.out.println(i);
}
}
} ///:~

RETURN
Sus funciones son las mismas que en C++. Cuando se llama a un procedimiento ( que en OOP se denominó método) al encontrarse con una sentencia return se pasa el valor especificado al código que llamó a dicho método y se devuelve el control al código invocador. Su misión tiene que ver con el control de flujo: se deja de ejecutar código secuencialmente y se pasa al código que invocó al método.
Esta sentencia también está profundamente relacionada con los métodos, ya que es la sentencia que le permite devolver al método un valor. Podíamos haber esperado ha hablar de métodos para introducir esta sentencia, pero hemos decidido introducirla aquí por tener una función relacionada, entre otras cosas, con control de flujo. En el ejemplo 7 ya se ha ejemplificado su uso.


Break y continue
 No se tratan de un bucle, pero sí de una sentencia íntimamente relacionada con estos. El encontrarse una sentencia break en el cuerpo de cualquier bucle detiene la ejecución del cuerpo del bucle y sale de este, continuándose ejecutando el código que hay tras el bucle.
Esta sentencia también se puede usar para forzar la salida del bloque de ejecución de una instrucción condicional (esto ya se vio con switch).
Continue también detiene la ejecución del cuerpo del bucle, pero en esta ocasión no se sale del bucle, sino que se pasa a la siguiente iteración de este.
Observaremos el funcionamiento de ambos en un mismo ejemplo:



public class ejemplo7 {
// Método que podremos invovar como test(int a, int b) y que
// devolverá -1 si a < b, +1 si a > b y 0 si a == b.
static int test(int val, int val2) {
int result = 0;
if(val > val2)
result = +1;
else if(val < val2)
result = -1;
else
result = 0;
return result;
}
public static void main(String[] args) {
//Imprimimos por consola el resultado de realizar unos
//cuantos test.
System.out.println(test(10, 5));
System.out.println(test(5, 10));
System.out.println(test(5, 5));
}
} ///:~
El modo de ejecución de un programa en Java en ausencia de elementos de control de flujo es secuencial, es decir una instrucción se ejecuta detrás de otra y sólo se ejecuta una vez. Esto nos permite hace programas muy limitados; para evitarlo se introducen estructuras de control de flujo.

Las estructuras de control de flujo de Java son la típicas de cualquier lenguaje de programación, por lo que supondremos que todos estáis familiarizados con ellas y se explicaran con poco detenimiento.


Copyright (c) 2003, Abraham Otero. Este documento puede ser distribuido sólo bajo los términos y
condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se
encuentra en
Para cualquier duda, consulta, insulto o tirón de orejas sobre este tutorial dirigirse a
http://www.javahispano.org/licencias/).abraham@javahispano.org.




SENTENCIAS CONDICIONALES