Saltar al contenido
condicionales.java · devschool

if, else y switch en Java

Lección 5 de 26 · 9 min de lectura · Actualizado el

En esta lección
  1. if y else
  2. else if: varias alternativas
  3. Condiciones compuestas y anidadas
  4. switch clásico
  5. switch con flechas
  6. switch como expresión
  7. switch con enum
  8. Pattern matching en switch (breve)
  9. ¿if o switch?
  10. Errores frecuentes
  11. Resumen

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.
  • else es opcional y se ejecuta cuando la condición es false.

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");
}
  • switch evalúa la expresión y salta al case que coincide.
  • break sale del switch.
  • default se 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 break olvidado. 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 int o String eso obliga a poner default.
  • 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ónMejor opción
Rangos (nota >= 5, edad < 18)if / else if
Condiciones con && o ||if
Una variable comparada con muchos valores concretosswitch
Elegir un valor según una opciónswitch expresión (o ternario si son dos)
Valores de un enumswitch

Errores frecuentes

  • Punto y coma tras el if: if (edad >= 18); termina el if ahí mismo y el bloque se ejecuta siempre.
  • Usar = en lugar de ==: if (edad = 18) no compila.
  • Comparar String con ==: usa equals (en switch Java ya usa equals por dentro).
  • Olvidar break en el switch clásico: provoca fall-through.
  • Orden incorrecto en else if: la condición más amplia debe ir al final.
  • switch expresión incompleto: si no cubres todos los casos ni pones default, no compila.

Resumen

  • if (condicion) { } else { }: la condición debe ser boolean.
  • else if encadena alternativas; solo se ejecuta la primera que se cumple.
  • El switch clásico usa case valor: y necesita break para no caer al siguiente caso.
  • El switch con flechas (case valor ->) no tiene fall-through y agrupa valores con comas.
  • Como expresión, switch devuelve un valor, debe ser exhaustivo y usa yield en bloques.
  • Con enum no necesitas default si 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

[Java] ¿Qué imprime este código?
int nivel = 1;
switch (nivel) {
    case 1:
        System.out.print("A");
    case 2:
        System.out.print("B");
        break;
    case 3:
        System.out.print("C");
}

[Java] ¿Qué imprime este código?
int nota = 9;
if (nota >= 5) {
    System.out.println("Aprobado");
} else if (nota >= 9) {
    System.out.println("Sobresaliente");
} else {
    System.out.println("Suspenso");
}

¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.