El mecanismo try-catch-finally

y try-with-resources

try-catch y multi-catch

Un bloque try puede tener múltiples catch. Se evalúan en orden: se ejecuta el primer catch cuyo tipo coincida con la excepción lanzada. Coloca los tipos más específicos primero — un catch (Exception e) antes de uno más específico causaría un error de compilación por código inalcanzable.

// try-catch básico
try {
    int resultado = 10 / 0;            // lanza ArithmeticException
    String s = null;
    s.length();                        // lanza NullPointerException
} catch (ArithmeticException e) {
    System.err.println("División por cero: " + e.getMessage());
} catch (NullPointerException e) {
    System.err.println("Referencia nula: " + e.getMessage());
} catch (Exception e) {
    // catch de excepción base: captura cualquier excepción no capturada antes
    System.err.println("Error inesperado: " + e.getMessage());
}

// Multi-catch (Java 7+): múltiples excepciones del mismo manejador
try {
    // código que puede lanzar varias excepciones no relacionadas
} catch (IOException | SQLException e) {
    System.err.println("Error de E/S o BBDD: " + e.getMessage());
}

finally

El bloque finally se ejecuta siempre: si el try termina normalmente, si lanza una excepción o si hay un return. Era el mecanismo de liberación de recursos antes de try-with-resources. Hoy su uso principal es para lógica de limpieza que no está ligada a un AutoCloseable.

// finally: se ejecuta siempre, con o sin excepción
Connection con = null;
try {
    con = obtenerConexion();
    // operaciones con la conexión...
} catch (SQLException e) {
    System.err.println("Error SQL: " + e.getMessage());
} finally {
    // garantizado: se ejecuta aunque haya excepción
    if (con != null) {
        try { con.close(); } catch (SQLException ignored) { }
    }
}

// Nota: si finally contiene un return, suprime cualquier excepción lanzada en try
// Evitar return en finally — es un anti-patrón que hace difícil de depurar el código

try-with-resources

Cualquier objeto que implemente AutoCloseable puede declararse en el try. La JVM garantiza que se llama a close() en orden inverso al de declaración, incluso si se lanza una excepción. Úsalo para todos los recursos que requieren cierre: ficheros, conexiones, streams, etc.

// try-with-resources (Java 7+): cierre automático de AutoCloseable
// Reemplaza el patrón try-catch-finally anterior — úsalo siempre

try (Connection con = dataSource.getConnection();
     PreparedStatement ps = con.prepareStatement("SELECT * FROM pedidos WHERE id = ?")) {

    ps.setLong(1, pedidoId);
    try (ResultSet rs = ps.executeQuery()) {
        while (rs.next()) {
            System.out.println(rs.getString("descripcion"));
        }
    } // rs se cierra aquí
} catch (SQLException e) {
    throw new RuntimeException("Error al buscar pedido " + pedidoId, e);
}
// con y ps se cierran aquí en orden inverso, incluso si hubo excepción

Excepciones suprimidas

Si tanto el bloque try como close() lanzan excepciones, try-with-resources preserva la excepción principal y adjunta la de close() como excepción suprimida. Con el patrón finally manual, la excepción de close() sobreescribía y perdía la excepción original.

// Excepciones suprimidas: cuando close() lanza excepción y ya hay una activa
// Java gestiona esto automáticamente en try-with-resources

try (MiRecurso r = new MiRecurso()) {
    throw new RuntimeException("excepción principal");
    // r.close() también lanza excepción
} catch (RuntimeException e) {
    System.out.println("Principal: " + e.getMessage());
    for (Throwable suprimida : e.getSuppressed()) {
        System.out.println("Suprimida: " + suprimida.getMessage());
    }
}
// Antes de Java 7 con finally manual, la excepción de close() sobreescribía la principal
Regla: usa try-with-resources para cualquier recurso AutoCloseable. Nunca dejes de cerrar recursos en finally sin este patrón — es propenso a bugs sutiles y más verboso. El compilador genera el código correcto para todas las combinaciones de excepciones automáticamente.

Siguiente apartado → Jerarquía de excepciones: checked, unchecked y Error

Índice de la sección

Índice del curso