CodeGym /Cursos /JAVA 25 SELF /Gestión avanzada de excepciones y buenas prácticas

Gestión avanzada de excepciones y buenas prácticas

JAVA 25 SELF
Nivel 24 , Lección 3
Disponible

1. Múltiples catch: manejo de distintas excepciones

En programas reales, un mismo bloque de código puede lanzar distintos tipos de excepciones. Por ejemplo, al leer un archivo puede aparecer tanto FileNotFoundException como IOException, y al analizar datos — también NumberFormatException. Para manejar correctamente cada situación, en Java se pueden utilizar varios bloques catch seguidos.

Sintaxis

try {
    // operaciones peligrosas
} catch (FileNotFoundException e) {
    System.out.println("Archivo no encontrado: " + e.getMessage());
} catch (IOException e) {
    System.out.println("Error de entrada/salida: " + e.getMessage());
} catch (NumberFormatException e) {
    System.out.println("Formato de número no válido: " + e.getMessage());
}

Punto importante:
¡Los bloques catch deben ir de los más específicos a los más generales! Si primero escribes catch (Exception e), los demás bloques serán inalcanzables y el compilador dará un error.

¿Por qué es importante?

  • Tratamiento específico: Puedes reaccionar de manera distinta ante diferentes errores (por ejemplo, proponer elegir otro archivo o repetir la entrada).
  • Legibilidad: El código se vuelve más claro — se ve qué errores se esperan y cómo se manejan.

2. catch con varios tipos (multi-catch)

A veces distintos tipos de excepciones requieren el mismo manejo. Por ejemplo, quieres simplemente mostrar un mensaje de error o registrarlo, independientemente de si fue un error de lectura de archivo o de conversión de número.

Desde Java 7 existe la sintaxis de multi-catch, que permite agrupar varios tipos de excepciones en un mismo bloque:

try {
    // operación peligrosa
} catch (IOException | NumberFormatException e) {
    System.out.println("Error al procesar el archivo o el número: " + e.getMessage());
}

Cómo funciona:

  • Los tipos de excepción se indican separados por la barra vertical (|).
  • La variable e tendrá el tipo de la clase base más general (normalmente Exception).
  • Dentro del bloque no se puede asignar un nuevo valor a la variable e — se considera final automáticamente.

Ejemplo:

try {
    BufferedReader reader = new BufferedReader(new FileReader("numbers.txt"));
    String line = reader.readLine();
    int number = Integer.parseInt(line);
    System.out.println("Número: " + number);
    reader.close();
} catch (IOException | NumberFormatException e) {
    System.out.println("Error: " + e.getMessage());
}

3. Buenas prácticas para el manejo de excepciones

No silencies las excepciones

Malo:

try {
    // algo peligroso
} catch (Exception e) {
    // ¡no hacemos nada!
}

¿Por qué es malo?
Un bloque catch vacío «silencia» el error: pierdes la información sobre la causa del fallo y el programa se vuelve difícil de depurar.

Mejor: como mínimo, muestra un mensaje o registra el error.

catch (Exception e) {
    e.printStackTrace();
}

Si no puedes manejar la excepción — propágala:

catch (IOException e) {
    throw e; // o throw new RuntimeException(e);
}

Lanza las excepciones más específicas

Si escribes tus propios métodos o API, lanza siempre excepciones lo más concretas posible, y no simplemente Exception o RuntimeException. Esto hace que tu código y tu interfaz sean más comprensibles para otros desarrolladores.

Ejemplo:

public void withdraw(double amount) throws InsufficientFundsException {
    if (amount > balance) {
        throw new InsufficientFundsException("Fondos insuficientes");
    }
    // ...
}

No uses las excepciones para controlar el flujo del programa

Las excepciones están pensadas para manejar situaciones excepcionales, es decir, errores que no deberían ocurrir en el curso normal del programa. No las uses para la lógica normal (por ejemplo, para salir de un bucle o comprobar condiciones).

Malo:

try {
    while (true) {
        String line = reader.readLine();
        if (line == null) break;
        // procesamiento de la línea
    }
} catch (Exception e) {
    // usamos una excepción para salir del bucle — ¡mal!
}

Bien:

String line;
while ((line = reader.readLine()) != null) {
    // procesamiento de la línea
}

4. Ejemplos prácticos

Ejemplo: manejar distintos errores de forma diferente

try {
    BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
    String line = reader.readLine();
    int number = Integer.parseInt(line);
    System.out.println("Número: " + number);
    reader.close();
} catch (FileNotFoundException e) {
    System.out.println("¡Archivo no encontrado!");
} catch (IOException e) {
    System.out.println("¡Error de lectura del archivo!");
} catch (NumberFormatException e) {
    System.out.println("¡El archivo no contiene un número!");
}

Ejemplo: multi-catch para un manejo uniforme

try {
    // algo peligroso
} catch (IOException | NumberFormatException e) {
    System.out.println("Error: " + e.getMessage());
}

5. Matices importantes y errores comunes

Error n.º 1: Orden incorrecto de los bloques catch. Primero deben ir las excepciones más específicas y luego — las generales. De lo contrario, nunca se alcanzará el bloque más amplio.

Error n.º 2: Uso de tipos relacionados en un multi-catch. Por ejemplo, catch (IOException | Exception e) no compilará porque IOException hereda de Exception.

Error n.º 3: Intentar modificar la variable e en un multi-catch. En este caso e se considera final — no se le puede asignar un nuevo valor.

Error n.º 4: Bloques catch vacíos. Ignorar errores conduce a fallos «silenciosos». Como mínimo, muestra un mensaje o registra la excepción.

Error n.º 5: Atrapar todos los Exception indiscriminadamente. Usar catch (Exception e) oculta problemas reales y dificulta la depuración. Es mejor capturar solo las excepciones esperadas.

1
Tarea
JAVA 25 SELF, nivel 24, lección 3
Bloqueada
Informe financiero: Diagnóstico preciso de problemas con los datos
Informe financiero: Diagnóstico preciso de problemas con los datos
1
Tarea
JAVA 25 SELF, nivel 24, lección 3
Bloqueada
Configuración del juego: Respuesta unificada ante fallos de carga
Configuración del juego: Respuesta unificada ante fallos de carga
1
Tarea
JAVA 25 SELF, nivel 24, lección 3
Bloqueada
Archivo secreto: Prioridad de acceso a datos confidenciales
Archivo secreto: Prioridad de acceso a datos confidenciales
1
Tarea
JAVA 25 SELF, nivel 24, lección 3
Bloqueada
Servicio de registro: ¡Ningún error debe perderse!
Servicio de registro: ¡Ningún error debe perderse!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION