Menu
Coddy logo textTech

Errores Checked vs Unchecked

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

Has visto que la jerarquía de excepciones de Java se divide en diferentes ramas. La distinción clave que debes entender es entre las excepciones comprobadas y las no comprobadas. Esto afecta a cómo debes gestionarlas en tu código.

Las excepciones comprobadas son excepciones que el compilador te obliga a gestionar. Extienden directamente Exception (no a través de RuntimeException). Debes capturarlas o declararlas con throws:

// Debe manejar IOException - es checked
public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);  // Puede lanzar IOException
}

// O capturarla
public void readFileSafe(String path) {
    try {
        FileReader reader = new FileReader(path);
    } catch (IOException e) {
        System.out.println("File error: " + e.getMessage());
    }
}

Las excepciones no comprobadas extienden RuntimeException. El compilador no requiere que las gestiones. Normalmente indican errores de programación, como referencias nulas o acceso no válido a un array:

// No se necesita declaración throws
public int divide(int a, int b) {
    return a / b;  // Puede lanzar ArithmeticException (no comprobada)
}

String name = null;
name.length();  // NullPointerException (no comprobada)

Al crear excepciones personalizadas, elige la clase principal según cómo quieras que las personas que llaman las gestionen. Usa excepciones comprobadas para las condiciones recuperables que quien llama debería anticipar. Usa excepciones no comprobadas para errores de programación que no deberían ocurrir en un código correcto.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de verificación de edad que demuestre la diferencia clave entre las excepciones comprobadas y no comprobadas! Crearás excepciones personalizadas de ambos tipos y verás cómo el compilador las trata de manera diferente.

Organizarás tu código en cuatro archivos:

  • InvalidAgeException.java: Crea una excepción comprobada para los errores de validación de edad. Esta excepción debe extender directamente Exception, lo que significa que los llamadores estarán obligados a gestionarla. Incluye un constructor que acepte un mensaje y se lo pase a la clase padre.
  • NegativeAgeException.java: Crea una excepción no comprobada para cuando alguien proporcione una edad negativa (un error de programación que no debería ocurrir con una entrada correcta). Esta debe extender RuntimeException. Incluye un constructor que acepte y pase un mensaje a la clase padre.
  • AgeVerifier.java: Crea una clase que valide edades usando ambos tipos de excepciones. Incluye dos métodos estáticos:

    verifyAge(int age): este método debe lanzar NegativeAgeException (no comprobada) con el mensaje "Age cannot be negative: [age]" si la edad es menor que 0. Si la edad es menor que 18, lanza InvalidAgeException (comprobada) con el mensaje "Must be 18 or older: [age]". De lo contrario, imprime Age [age] verified successfully. Como este método lanza una excepción comprobada, debes declararlo con throws InvalidAgeException.

    verifyAgeUncheckedOnly(int age): este método solo usa excepciones no comprobadas. Si la edad es negativa, lanza NegativeAgeException con el mismo formato de mensaje. Si la edad es menor que 18, lanza una IllegalArgumentException con el mensaje "Too young: [age]". De lo contrario, imprime Age [age] verified (unchecked method). ¡Observa que este método no necesita ninguna declaración throws!

  • Main.java: ¡Integra tu sistema de verificación! Recibirás una entrada: una edad (entero).

    Primero, imprime === Checked Exception Method === y llama a verifyAge con la edad de entrada. Como lanza una excepción comprobada, debes incluirlo en un bloque try-catch. Captura InvalidAgeException e imprime Checked exception caught: [message]. Captura también NegativeAgeException e imprime Unchecked exception caught: [message].

    Después, imprime una línea en blanco y === Unchecked Exception Method ===. Llama a verifyAgeUncheckedOnly con la misma edad. Aunque este método puede lanzar excepciones, no estás obligado a capturarlas. Sin embargo, inclúyelo de todos modos en un bloque try-catch para gestionar los errores correctamente. Captura NegativeAgeException e imprime Runtime exception caught: [message]. Captura IllegalArgumentException e imprime Illegal argument caught: [message].

Recibirás una entrada: un entero que representa la edad que se debe verificar.

Observa la diferencia clave: el método con la excepción comprobada requiere una declaración throws y obliga a los llamadores a gestionarla, mientras que el método no comprobado se compila correctamente sin ningún manejo de excepciones. ¡Esta es la distinción fundamental entre las excepciones comprobadas y no comprobadas en Java!

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int age = scanner.nextInt();
        
        // TODO: Test the checked exception method
        // Print: "=== Checked Exception Method ==="
        // Llama a AgeVerifier.verifyAge(age) en un try-catch
        // - Catch InvalidAgeException: print "Checked exception caught: [message]"
        // - Catch NegativeAgeException: print "Unchecked exception caught: [message]"
        
        
        // TODO: Print a blank line, then "=== Unchecked Exception Method ==="
        // Llama a AgeVerifier.verifyAgeUncheckedOnly(age) en un try-catch
        // - Catch NegativeAgeException: print "Runtime exception caught: [message]"
        // - Catch IllegalArgumentException: print "Illegal argument caught: [message]"
        
    }
}
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