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 necesitas excepciones específicas del dominio de tu aplicación. Las excepciones personalizadas te 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 comprobada, extiende Exception:
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}Para una excepción no comprobada, 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 principal, lo que permite acceder a él mediante getMessage(). Después, 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;
}
// Usándolo
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 realizan las llamadas gestionen de forma diferente condiciones de error específicas. Son especialmente valiosas al crear API o bibliotecas en las que es importante comunicar claramente los errores.
Desafío
Fácil¡Construyamos un sistema de reserva de entradas que utilice excepciones personalizadas para gestionar distintos escenarios de error! Crearás tipos de excepción significativos que comunicarán claramente qué salió mal al reservar entradas.
Organizarás tu código en cuatro archivos:
TicketSoldOutException.java: Crea una excepción comprobada personalizada (extiendeException) para cuando ya no haya entradas disponibles. Tu excepción debe aceptar un mensaje en su constructor y pasarlo a la clase principal mediantesuper(message).InvalidSeatException.java: Crea una excepción no comprobada personalizada (extiendeRuntimeException) para cuando alguien intente reservar un número de asiento no válido. Esta excepción también debe aceptar y pasar un mensaje a su clase principal.TicketBooth.java: Crea una clase que gestione la venta de entradas. Tu taquilla debe llevar el control del número total de asientos disponibles y del 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 entradas (los asientos disponibles son 0 o menos), lanza unaTicketSoldOutExceptioncon el mensaje"No tickets remaining". Si el número de asiento es menor que 1 o mayor que el total de asientos, lanza unaInvalidSeatExceptioncon el mensaje"Seat [seatNumber] does not exist". De lo contrario, disminuye en 1 los asientos disponibles e imprimeBooked seat [seatNumber] successfully.Un método
getAvailableSeats()que devuelva el número actual de asientos disponibles.Main.java: ¡Reúne tu sistema de reserva de entradas! Recibirás dos entradas: el número total de asientos y un número de asiento que reservar.Crea un
TicketBoothcon el total de asientos indicado. Después, intenta reservar el número de asiento especificado dentro de un bloque try-catch. ComoTicketSoldOutExceptiones comprobada, debes gestionarla. Captura primeroTicketSoldOutExceptione imprimeBooking failed: [exception message]. Después, capturaInvalidSeatExceptione imprime el mismo formato:Booking failed: [exception message].Después del bloque try-catch, imprime
Remaining seats: [count]usando el método getter.
Recibirás dos entradas en este orden: total de asientos (entero) y número de asiento que reservar (entero).
Observa cómo las excepciones comprobadas obligan a quienes las llaman a gestionarlas (con try-catch o throws), mientras que las excepciones no comprobadas no requieren una gestión explícita. ¡Elige el tipo de excepción según si es un error que quienes llaman deberían prever y del que deberían 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: Crea un TicketBooth con el total de asientos dado
// TODO: Usa un bloque try-catch para intentar reservar el asiento
// - Captura TicketSoldOutException primero e imprime "Booking failed: [exception message]"
// - Captura InvalidSeatException e imprime "Booking failed: [exception message]"
// TODO: After the try-catch, print "Remaining seats: [count]"
}
}
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
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado10Manejo de excepciones en POO
Jerarquía de clases de excepcionesExcepciones personalizadasErrores Checked vs UncheckedPatrón Try With ResourcesResumen - Usuario validado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón IteratorPractica por tu cuenta: Compilador de Java online