if, else y switch en Java
En esta lección
Los condicionales permiten que un programa haga una cosa u otra según los datos: aplicar un descuento si el cliente es socio, mostrar “Aprobado” o “Suspenso”, elegir la opción de un menú. En esta lección verás if, else if y else, cuándo conviene anidarlos, y las dos caras de switch: la clásica, con break, y la moderna de Java 21, con flechas y capaz de devolver valores.
if y else
int edad = 16;
if (edad >= 18) {
System.out.println("Puedes votar");
} else {
System.out.println("Todavía no puedes votar"); // Todavía no puedes votar
}
- La condición va entre paréntesis y tiene que dar un
boolean. - El bloque entre llaves se ejecuta solo si la condición es
true. elsees opcional y se ejecuta cuando la condición esfalse.
A diferencia de JavaScript o Python, Java no acepta otros valores como condición: if (1) o if (nombre) no compilan. Tiene que ser una comparación, una variable boolean o un método que devuelva boolean:
boolean esSocio = true;
String cupon = "VERANO";
if (esSocio) {
System.out.println("Descuento de socio aplicado");
}
if (cupon.isEmpty()) {
System.out.println("No has usado cupón");
}
Llaves siempre
Si el bloque tiene una sola instrucción, Java permite omitir las llaves. No lo hagas: es fácil añadir después una segunda línea que parece estar dentro del if y no lo está.
int stock = 5;
if (stock == 0)
System.out.println("Agotado");
System.out.println("Avisa al proveedor"); // se ejecuta siempre
La sangría engaña: la segunda línea está fuera del if. Con llaves no hay dudas.
else if: varias alternativas
Cuando hay más de dos caminos, encadena condiciones con else if:
double nota = 7.5;
if (nota >= 9) {
System.out.println("Sobresaliente");
} else if (nota >= 7) {
System.out.println("Notable"); // Notable
} else if (nota >= 5) {
System.out.println("Aprobado");
} else {
System.out.println("Suspenso");
}
Las condiciones se comprueban de arriba abajo y solo se ejecuta la primera que se cumple; las demás ni se miran. Por eso el orden importa. Si pusieras nota >= 5 la primera, un 9,5 mostraría “Aprobado”.
Gracias a ese orden, no hace falta escribir nota >= 7 && nota < 9: si has llegado al segundo else if, ya sabes que la nota es menor que 9.
Condiciones compuestas y anidadas
Puedes combinar condiciones con &&, || y ! (los tienes en operadores):
int edad = 25;
boolean carnet = true;
if (edad >= 18 && carnet) {
System.out.println("Puede alquilar el coche"); // Puede alquilar el coche
}
También puedes poner un if dentro de otro. Es útil cuando la segunda pregunta solo tiene sentido si la primera se cumple:
double importe = 120;
boolean esSocio = false;
if (importe >= 100) {
if (esSocio) {
System.out.println("Envío gratis y 10 % de descuento");
} else {
System.out.println("Envío gratis"); // Envío gratis
}
} else {
System.out.println("Envío: 4,99 euros");
}
Consejo: más de dos o tres niveles de anidación se leen mal. Si te ocurre, prueba a combinar condiciones con
&&o a sacar parte de la lógica a un método con un nombre claro.
switch clásico
Cuando comparas una misma variable con muchos valores concretos, switch es más limpio que una cadena de else if:
int dia = 3;
switch (dia) {
case 1:
System.out.println("Lunes");
break;
case 2:
System.out.println("Martes");
break;
case 3:
System.out.println("Miércoles"); // Miércoles
break;
default:
System.out.println("Otro día");
}
switchevalúa la expresión y salta alcaseque coincide.breaksale delswitch.defaultse ejecuta si no coincide ningún caso (es opcional).
switch funciona con int, char, byte, short, String, enum y sus clases envoltorio. No funciona con double, long ni boolean, ni con rangos: para nota >= 5 necesitas un if.
Fall-through: cuando falta el break
Sin break, Java no se detiene al terminar un caso: sigue ejecutando los siguientes, sin comprobar su valor. A esto se le llama fall-through (“caer a través”):
int opcion = 2;
switch (opcion) {
case 1:
System.out.println("Uno");
case 2:
System.out.println("Dos");
case 3:
System.out.println("Tres");
default:
System.out.println("Fin");
}
Dos
Tres
Fin
Casi siempre es un error. Solo tiene una utilidad legítima: agrupar varios casos que hacen lo mismo.
int mes = 4;
int dias;
switch (mes) {
case 4:
case 6:
case 9:
case 11:
dias = 30;
break;
case 2:
dias = 28;
break;
default:
dias = 31;
}
System.out.println(dias); // 30
switch con flechas
Desde Java 14 existe una sintaxis nueva con -> que no tiene fall-through: cada caso ejecuta lo suyo y termina. Además, permite agrupar valores con comas:
int mes = 2;
switch (mes) {
case 4, 6, 9, 11 -> System.out.println("30 días");
case 2 -> System.out.println("28 o 29 días"); // 28 o 29 días
default -> System.out.println("31 días");
}
Si un caso necesita varias instrucciones, van entre llaves:
String comando = "guardar";
switch (comando) {
case "abrir" -> System.out.println("Abriendo archivo...");
case "guardar" -> {
System.out.println("Comprobando cambios..."); // Comprobando cambios...
System.out.println("Archivo guardado"); // Archivo guardado
}
default -> System.out.println("Comando desconocido");
}
Con String, la comparación distingue mayúsculas: "Guardar" no coincide con "guardar". Si el texto viene del usuario, normalízalo antes con comando.toLowerCase().
Consejo: en código nuevo, usa siempre la forma con flechas. Es más corta y elimina el error del
breakolvidado. Aun así, aprende la clásica: aparece en mucho código existente y en exámenes.
switch como expresión
La forma con flechas también puede devolver un valor, que guardas en una variable:
String dia = "sábado";
String tipo = switch (dia) {
case "sábado", "domingo" -> "Fin de semana";
case "viernes" -> "Casi fin de semana";
default -> "Día laborable";
};
System.out.println(tipo); // Fin de semana
Reglas de un switch expresión:
- Debe cubrir todos los casos posibles; con
intoStringeso obliga a ponerdefault. - Termina en punto y coma, porque es parte de una asignación.
- Si un caso necesita varias instrucciones, usa llaves y devuelve el valor con
yield:
int unidades = 12;
String tamanio = "grande";
double precio = switch (tamanio) {
case "pequenio" -> 2.0;
case "mediano" -> 3.5;
case "grande" -> {
double base = 5.0;
if (unidades >= 10) {
base = base * 0.9; // 10 % de descuento por volumen
}
yield base;
}
default -> 0;
};
System.out.println(precio); // 4.5
yield es como un return, pero solo para el switch: le da su valor y termina el caso.
switch con enum
Un enum es un tipo con un conjunto cerrado de valores (lo verás a fondo en enumeraciones). Encaja perfectamente con switch: los casos se escriben sin el nombre del tipo y, en un switch expresión, no hace falta default si cubres todos los valores.
enum Semaforo { ROJO, AMBAR, VERDE }
public class Cruce {
public static void main(String[] args) {
Semaforo luz = Semaforo.AMBAR;
String accion = switch (luz) {
case ROJO -> "Para";
case AMBAR -> "Precaución";
case VERDE -> "Pasa";
};
System.out.println(accion); // Precaución
}
}
Si mañana añades un valor APAGADO al enum, el compilador te avisará de que el switch ya no cubre todos los casos. Es una red de seguridad muy valiosa.
Pattern matching en switch (breve)
Java 21 permite que un switch distinga por tipo y, en el mismo paso, cree una variable del tipo correcto. También admite condiciones extra con when:
Object dato = 42;
String descripcion = switch (dato) {
case Integer n when n < 0 -> "Entero negativo";
case Integer n -> "Entero: " + n;
case String s -> "Texto de " + s.length() + " letras";
default -> "Otro tipo";
};
System.out.println(descripcion); // Entero: 42
Lo usarás sobre todo con jerarquías de clases; lo tienes explicado en polimorfismo.
¿if o switch?
| Situación | Mejor opción |
|---|---|
Rangos (nota >= 5, edad < 18) | if / else if |
Condiciones con && o || | if |
| Una variable comparada con muchos valores concretos | switch |
| Elegir un valor según una opción | switch expresión (o ternario si son dos) |
Valores de un enum | switch |
Errores frecuentes
- Punto y coma tras el
if:if (edad >= 18);termina elifahí mismo y el bloque se ejecuta siempre. - Usar
=en lugar de==:if (edad = 18)no compila. - Comparar
Stringcon==: usaequals(enswitchJava ya usaequalspor dentro). - Olvidar
breaken elswitchclásico: provoca fall-through. - Orden incorrecto en
else if: la condición más amplia debe ir al final. switchexpresión incompleto: si no cubres todos los casos ni ponesdefault, no compila.
Resumen
if (condicion) { } else { }: la condición debe serboolean.else ifencadena alternativas; solo se ejecuta la primera que se cumple.- El
switchclásico usacase valor:y necesitabreakpara no caer al siguiente caso. - El
switchcon flechas (case valor ->) no tiene fall-through y agrupa valores con comas. - Como expresión,
switchdevuelve un valor, debe ser exhaustivo y usayielden bloques. - Con
enumno necesitasdefaultsi cubres todos los valores.
Si quieres que tus programas decidan según lo que escribe el usuario, repasa cómo leer datos con Scanner. El siguiente paso es repetir instrucciones con bucles.
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.