CodeGym /Cursos /JAVA 25 SELF /Jerarquía de excepciones en Java

Jerarquía de excepciones en Java

JAVA 25 SELF
Nivel 24 , Lección 0
Disponible

1. Clase Throwable: la raíz de todas las excepciones

Ahora veremos en detalle cómo está diseñado el sistema de excepciones en Java: qué es Throwable, en qué se diferencian Exception y Error, y qué significan «comprobada» y «no comprobada». Es el fundamento para un manejo correcto de errores en tus programas.

En Java, todas las excepciones y errores son objetos que heredan de la clase java.lang.Throwable.
Throwable es el «progenitor» de toda la jerarquía de manejo de problemas en Java.

Esquemáticamente:

Throwable
├── Exception
└── Error

Throwable es la clase base de todo lo que puede ser «lanzado» (throw) y «capturado» (catch) en Java. No se utiliza directamente: sirve como base para tipos de error más concretos.

Exception — para errores «normales»

Exception es la clase base de todas las excepciones que pueden surgir en un programa y que se pueden y se deben manejar. Son errores «de trabajo»: problemas con archivos, red, entrada/salida, errores del usuario, etc. La mayoría de tus try-catch trabajará con subclases de Exception.

Ejemplos:

  • IOException — error al trabajar con archivos o la red.
  • SQLException — error al trabajar con la base de datos.
  • FileNotFoundException — archivo no encontrado.

Error — para errores fatales de la JVM

Error es la clase base de los errores que ocurren a nivel de la máquina virtual de Java (JVM). Suelen ser fallos críticos que el programa no puede ni debe manejar. Si ocurre Error, lo más probable es que la aplicación no pueda continuar.

Ejemplos:

  • OutOfMemoryError — memoria agotada.
  • StackOverflowError — desbordamiento de pila (por ejemplo, debido a recursión infinita).
  • NoClassDefFoundError — no se encontró la clase necesaria.

Importante:
Capturar y manejar Error casi siempre es una mala idea. No son errores de tu programa, sino fallos del entorno de ejecución.

2. Excepciones checked vs unchecked: ¿qué significa?

En Java, todas las excepciones se dividen en dos grandes grupos:

Excepciones comprobadas (Checked)

¿Qué son? Excepciones que el compilador obliga a manejar o a declarar explícitamente.

¿Cuándo ocurren? Suelen estar asociadas a recursos externos: archivos, red, bases de datos, entrada del usuario.

¿Cómo manejarlas? Hay que envolver el código en try-catch o añadir throws a la firma del método.

Ejemplos: IOException, SQLException, FileNotFoundException

Ejemplo:

public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path); // puede lanzar IOException
    // ...
}

Si no se manejan ni se propagan — ¡el programa no se compilará!

Excepciones no comprobadas (Unchecked)

¿Qué son? Excepciones que no requieren manejo obligatorio por parte del compilador.

¿Cuándo ocurren? Suelen ser errores en la lógica del programa: división por cero, salida de los límites de un array, acceso a null.

¿Cómo manejarlas? Se pueden capturar, pero no es obligatorio. Es mejor prevenir estos errores con comprobaciones.

¿Dónde en la jerarquía? Todas heredan de RuntimeException.

Ejemplos: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, ArithmeticException

Ejemplo:

int[] arr = {1, 2, 3};
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException

El compilador no te obliga a capturar esta excepción — pero el programa fallará cuando ocurra el error.

3. Toda la jerarquía en una sola imagen

graph TD
    Throwable --> Error
    Throwable --> Exception
    
    Exception --> RuntimeException
    Exception --> CheckedExceptions["(otras excepciones comprobadas)"]
    
    Error --> OutOfMemoryError
    Error --> StackOverflowError
    
    RuntimeException --> NullPointerException
    RuntimeException --> IndexOutOfBoundsException
    RuntimeException --> IllegalArgumentException

    %% Estilos
    style Throwable fill:#ffa64d,color:#000
    style Exception fill:#ffa64d,color:#000
    style CheckedExceptions fill:#ffa64d,color:#000
    
    style Error fill:#ff4d4d,color:#fff
    style OutOfMemoryError fill:#ff4d4d,color:#fff
    style StackOverflowError fill:#ff4d4d,color:#fff
    
    style RuntimeException fill:#4dff88,color:#000
    style NullPointerException fill:#4dff88,color:#000
    style IndexOutOfBoundsException fill:#4dff88,color:#000
    style IllegalArgumentException fill:#4dff88,color:#000

Tabla: diferencias principales

Grupo Clase padre ¿Requiere manejo? Ejemplos
Checked Exception
Exception
IOException, SQLException
Unchecked
RuntimeException
No
NullPointerException, IndexOutOfBoundsException
Error
Error
No
OutOfMemoryError, StackOverflowError

4. ¿Cómo se ve en el código?

Excepción comprobada: ejemplo con archivos

import java.io.*;

public class FileDemo {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("nofile.txt"); // FileNotFoundException (checked)
            int data = reader.read();
            System.out.println(data);
            reader.close();
        } catch (IOException e) {
            System.out.println("Error al trabajar con el archivo: " + e.getMessage());
        }
    }
}

¡El compilador te obligará a manejar IOException!

Excepción no comprobada: ejemplo de división por cero

public class ExceptionDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int c = a / b; // ArithmeticException (unchecked)
        System.out.println("Resultado: " + c);
    }
}

El compilador no exige manejo, pero el programa fallará.

5. ¿Para qué sirve la jerarquía de excepciones?

  • Flexibilidad de manejo: Puedes capturar tanto errores concretos (FileNotFoundException) como grupos enteros (IOException o Exception).
  • Reutilización de código: Puedes manejar de forma centralizada errores de un mismo tipo.
  • Limpieza del código: La lógica principal no se llena de comprobaciones para cada detalle.

Ejemplo:

try {
    // código peligroso
} catch (FileNotFoundException e) {
    System.out.println("¡Archivo no encontrado!");
} catch (IOException e) {
    System.out.println("¡Error de E/S!");
} catch (Exception e) {
    System.out.println("Algo ha salido mal: " + e.getMessage());
}

6. Errores típicos al trabajar con excepciones

Error n.º 1: ignorar las excepciones. Escribir catch (Exception e) {} — ¡malo! Pierdes información sobre la causa del error.

Error n.º 2: capturar demasiado. catch (Exception e) lo atrapa todo, incluso lo que no esperabas. Es mejor capturar solo las excepciones que sabes manejar.

Error n.º 3: capturar errores (Error). No conviene capturar Error si no estás escribiendo código de bajo nivel. Son problemas de la JVM, no de tu programa.

Error n.º 4: no distinguir entre checked y unchecked. ¡No todas las excepciones son iguales! Las checked requieren manejo (Exception); las unchecked, no (RuntimeException y sus subclases).

Error n.º 5: no añadir información a las excepciones. Si creas tus propias excepciones, añade siempre un mensaje informativo.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION