Menu
Coddy logo textTech

Excepciones personalizadas

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 60 de 87.

Las excepciones integradas de Java cubren muchos escenarios de error comunes, pero a veces se necesitan excepciones que sean específicas del dominio de su aplicación. Las excepciones personalizadas le permiten crear tipos de error significativos que comunican claramente qué salió mal.

Para crear una excepción personalizada, simplemente extiende una clase de excepción existente. Para una excepción verificada, extiende Exception:

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

Para una excepción no comprobada, extienda RuntimeException:

public class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String message) {
        super(message);
    }
}

La llamada super(message) pasa el mensaje de error a la clase padre, haciéndolo disponible a través de getMessage(). Luego puedes lanzar y capturar tu excepción personalizada como cualquier otra:

public void withdraw(double amount) throws InsufficientFundsException {
    if (amount > balance) {
        throw new InsufficientFundsException("Balance too low: " + balance);
    }
    balance -= amount;
}

// Uso
try {
    account.withdraw(1000);
} catch (InsufficientFundsException e) {
    System.out.println(e.getMessage());
}

Las excepciones personalizadas hacen que tu código sea más legible y permiten que quienes llaman al código manejen condiciones de error específicas de manera diferente. Son especialmente valiosas al construir APIs o librerías donde la comunicación clara de errores es importante.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de reserva de boletos que utiliza excepciones personalizadas para manejar diferentes escenarios de error! Crearás tipos de excepciones significativos que comuniquen claramente qué salió mal al reservar boletos.

Organizarás tu código en cuatro archivos:

  • TicketSoldOutException.java: Crea una excepción verificada (checked exception) personalizada (extiende de Exception) para cuando los boletos ya no estén disponibles. Tu excepción debe aceptar un mensaje en su constructor y pasarlo a la clase padre usando super(message).
  • InvalidSeatException.java: Crea una excepción no verificada (unchecked exception) personalizada (extiende de RuntimeException) para cuando alguien intente reservar un número de asiento inválido. Esta excepción también debe aceptar y pasar un mensaje a su padre.
  • TicketBooth.java: Crea una clase que gestione la venta de boletos. Tu taquilla debe rastrear el número total de asientos disponibles y el número de asiento válido más alto. Incluye:

    Un constructor que reciba el número total de asientos disponibles.

    Un método bookTicket(int seatNumber) que valide la reserva. Si no quedan boletos (los asientos disponibles son 0 o menos), lanza una TicketSoldOutException con el mensaje "No tickets remaining". Si el número de asiento es menor que 1 o mayor que el total de asientos, lanza una InvalidSeatException con el mensaje "Seat " + seatNumber + " does not exist". De lo contrario, disminuye los asientos disponibles en 1 e imprime "Booked seat " + seatNumber + " successfully".

    Un método getAvailableSeats() que devuelva el recuento actual de asientos disponibles.

  • Main.java: ¡Une tu sistema de boletos! Recibirás dos entradas: el número total de asientos y un número de asiento para reservar.

    Crea un TicketBooth con el total de asientos dado. Luego, intenta reservar el número de asiento especificado dentro de un bloque try-catch. Dado que TicketSoldOutException es verificada, debes manejarla. Captura TicketSoldOutException primero e imprime "Booking failed: " + e.getMessage(). Luego captura InvalidSeatException e imprime el mismo formato: "Booking failed: " + e.getMessage().

    Después del bloque try-catch, imprime "Remaining seats: " + booth.getAvailableSeats() usando el método getter.

Recibirás dos entradas en orden: total de asientos (entero) y número de asiento a reservar (entero).

Observa cómo las excepciones verificadas obligan a quienes llaman al método a manejarlas (con try-catch o throws), mientras que las excepciones no verificadas no requieren un manejo explícito. ¡Elige el tipo de excepción basándote en si el error es algo que quienes llaman al método deben anticipar y de lo cual deben recuperarse!

Hoja de referencia

Para crear una excepción personalizada, extiende una clase de excepción existente.

Para una excepción verificada (checked exception), extiende Exception:

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

Para una excepción no verificada (unchecked exception), extiende RuntimeException:

public class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String message) {
        super(message);
    }
}

La llamada super(message) pasa el mensaje de error a la clase base, haciéndolo disponible a través de getMessage().

Lanza y captura excepciones personalizadas como cualquier otra excepción:

public void withdraw(double amount) throws InsufficientFundsException {
    if (amount > balance) {
        throw new InsufficientFundsException("Balance too low: " + balance);
    }
    balance -= amount;
}

// Using it
try {
    account.withdraw(1000);
} catch (InsufficientFundsException e) {
    System.out.println(e.getMessage());
}

Las excepciones verificadas obligan a quienes llaman al método a manejarlas con try-catch o throws. Las excepciones no verificadas no requieren un manejo explícito. Elige basándote en si el error es algo que quienes llaman al método deben anticipar y de lo cual deben recuperarse.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int totalSeats = scanner.nextInt();
        int seatNumber = scanner.nextInt();
        
        // TODO: Crear un TicketBooth con el total de asientos dado
        
        // TODO: Usar un bloque try-catch para intentar reservar el asiento
        // - Capturar TicketSoldOutException primero e imprimir "Booking failed: [exception message]"
        // - Capturar InvalidSeatException e imprimir "Booking failed: [exception message]"
        
        // TODO: Después del try-catch, imprimir "Remaining seats: [count]"
    }
}
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