Menu
Coddy logo textTech

Jerarquía de clases de excepciones

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 59 de 87.

El sistema de manejo de excepciones de Java se basa en una jerarquía de clases bien organizada cuyo origen es la clase Throwable. Comprender esta jerarquía te ayuda a capturar y manejar las excepciones de forma más eficaz.

En la parte superior se encuentra Throwable, la clase principal de todas las excepciones y errores. Tiene dos subclases directas:

Throwable
├── Error          // Problemas serios (no captures estos)
└── Exception      // Problemas recuperables
    └── RuntimeException  // Excepciones no comprobadas

Error representa problemas graves que las aplicaciones no deberían intentar manejar, como OutOfMemoryError o StackOverflowError. Estos indican problemas fundamentales con la propia JVM.

Exception es la rama con la que trabajarás más. Se divide en dos categorías: excepciones comprobadas (subclases directas de Exception) y excepciones no comprobadas (subclases de RuntimeException).

// Clases de excepciones comunes
Exception
├── IOException           // Problemas de archivo/red
├── SQLException          // Problemas de base de datos
└── RuntimeException
    ├── NullPointerException
    ├── ArrayIndexOutOfBoundsException
    └── IllegalArgumentException

Como las excepciones son clases, siguen las reglas de herencia. Cuando capturas un tipo de excepción padre, también capturas todos sus tipos hijos:

try {
    // algo de código
} catch (Exception e) {
    // Captura TODAS las excepciones (demasiado amplio generalmente)
}
try {
    // algún código
} catch (RuntimeException e) {
    // Catches only runtime exceptions and subclasses
}

Esta jerarquía te permite ser tan específico o general como sea necesario al gestionar errores, y es la base para crear tus propias excepciones personalizadas.

challenge icon

Desafío

Fácil

¡Construyamos un analizador de excepciones que demuestre cómo funciona en la práctica la jerarquía de excepciones de Java! Crearás un sistema que capture excepciones en distintos niveles de especificidad e informe qué tipo se capturó.

Organizarás tu código en tres archivos:

  • ExceptionThrower.java: Crea una clase que pueda activar distintos tipos de excepciones según la entrada. Tu clase debe tener tres métodos estáticos:

    triggerRuntime(String type): según la cadena de tipo, lanza distintas excepciones en tiempo de ejecución:

    • Si type es "null", lanza una NullPointerException con el mensaje "Null value encountered"
    • Si type es "index", lanza una ArrayIndexOutOfBoundsException con el mensaje "Invalid index"
    • Si type es "argument", lanza una IllegalArgumentException con el mensaje "Bad argument"

    triggerArithmetic(): lanza una ArithmeticException con el mensaje "Division error"

    triggerGeneric(): lanza una IllegalStateException con el mensaje "Generic runtime error" (su jerarquía es Exception > RuntimeException > IllegalStateException)

  • ExceptionAnalyzer.java: Crea una clase que capture excepciones en distintos niveles de la jerarquía e identifique qué se capturó. Incluye estos métodos estáticos:

    analyzeSpecific(String type): llama a ExceptionThrower.triggerRuntime(type) dentro de un bloque try. Usa bloques catch separados para NullPointerException, ArrayIndexOutOfBoundsException e IllegalArgumentException. Para cada uno, imprime: Caught specific: [exception class simple name] seguido de Message: [exception message]

    analyzeWithParent(): llama a ExceptionThrower.triggerArithmetic() dentro de un bloque try. Captúrala usando RuntimeException (el tipo padre). Imprime: Caught via parent: RuntimeException seguido de Actual type: [exception class simple name]

    analyzeWithGrandparent(): llama a ExceptionThrower.triggerGeneric() dentro de un bloque try. Captúrala usando Exception (un nivel aún más alto en la jerarquía). Imprime: Caught via grandparent: Exception seguido de Actual type: [exception class simple name]

  • Main.java: ¡Une tu analizador de excepciones! Recibirás una entrada: una cadena con el tipo de excepción (ya sea "null", "index" o "argument").

    Primero, imprime === Specific Catch === y llama a analyzeSpecific con tu entrada.

    Después, imprime una línea en blanco, === Parent Catch === y llama a analyzeWithParent.

    Por último, imprime una línea en blanco, === Grandparent Catch === y llama a analyzeWithGrandparent.

Recibirás una entrada: el tipo de excepción que se activará ("null", "index" o "argument").

Usa e.getClass().getSimpleName() para obtener el nombre de clase de la excepción y e.getMessage() para recuperar su mensaje. Este desafío muestra cómo capturar un tipo de excepción padre también captura todos sus tipos derivados: ¡un concepto clave al decidir cuán específico debe ser el manejo de excepciones!

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String type = scanner.nextLine();
        
        // TODO: Print "=== Specific Catch ===" and call ExceptionAnalyzer.analyzeSpecific(type)
        
        // TODO: Imprime una línea en blanco, luego "=== Parent Catch ===", luego llama a ExceptionAnalyzer.analyzeWithParent()
        
        // TODO: Print a blank line, then "=== Grandparent Catch ===", then call ExceptionAnalyzer.analyzeWithGrandparent()
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online