Exceções Personalizadas
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 60 de 87.
As exceções integradas do Java abrangem muitos cenários comuns de erro, mas às vezes você precisa de exceções específicas do domínio da sua aplicação. Exceções personalizadas permitem criar tipos de erro significativos que comunicam claramente o que deu errado.
Para criar uma exceção customizada, basta estender uma classe de exceção existente. Para uma exceção verificada, estenda Exception:
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}Para uma exceção não verificada, estenda RuntimeException:
public class InvalidAgeException extends RuntimeException {
public InvalidAgeException(String message) {
super(message);
}
}A chamada super(message) passa a mensagem de erro para a classe pai, tornando-a disponível por meio de getMessage(). Você pode então usar throw e catch com sua exceção custom, como qualquer outra:
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException("Balance too low: " + balance);
}
balance -= amount;
}
// Usando isso
try {
account.withdraw(1000);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
}Exceções customizadas tornam seu código mais legível e permitem que os chamadores tratem condições de erro específicas de maneira diferente. Elas são especialmente valiosas ao criar APIs ou bibliotecas em que uma comunicação clara sobre erros é importante.
Desafio
FácilVamos criar um sistema de reserva de ingressos que usa exceções personalizadas para lidar com diferentes cenários de erro! Você criará tipos de exceção significativos que comunicarão claramente o que deu errado ao reservar ingressos.
Você organizará seu código em quatro arquivos:
TicketSoldOutException.java: Crie uma exceção verificada personalizada (estendeException) para quando não houver mais ingressos disponíveis. Sua exceção deve aceitar uma mensagem em seu construtor e passá-la para a classe pai usandosuper(message).InvalidSeatException.java: Crie uma exceção não verificada personalizada (estendeRuntimeException) para quando alguém tentar reservar um número de assento inválido. Essa exceção também deve aceitar e passar uma mensagem para sua classe pai.TicketBooth.java: Crie uma classe que gerencie a venda de ingressos. Seu guichê deve acompanhar o número total de assentos disponíveis e o maior número de assento válido. Inclua:Um construtor que receba o número total de assentos disponíveis.
Um método
bookTicket(int seatNumber)que valide a reserva. Se não restarem ingressos (o número de assentos disponíveis for 0 ou menos), lance umaTicketSoldOutExceptioncom a mensagem"No tickets remaining". Se o número do assento for menor que 1 ou maior que o total de assentos, lance umaInvalidSeatExceptioncom a mensagem"Seat [seatNumber] does not exist". Caso contrário, diminua o número de assentos disponíveis em 1 e imprimaBooked seat [seatNumber] successfully.Um método
getAvailableSeats()que retorne a contagem atual de assentos disponíveis.Main.java: Reúna seu sistema de ingressos! Você receberá duas entradas: o número total de assentos e um número de assento para reservar.Crie um
TicketBoothcom o total de assentos fornecido. Em seguida, tente reservar o número de assento especificado dentro de um bloco try-catch. ComoTicketSoldOutExceptioné verificada, você deve tratá-la. CaptureTicketSoldOutExceptionprimeiro e imprimaBooking failed: [exception message]. Em seguida, captureInvalidSeatExceptione imprima o mesmo formato:Booking failed: [exception message].Após o bloco try-catch, imprima
Remaining seats: [count]usando o método getter.
Você receberá duas entradas, nesta ordem: total de assentos (inteiro) e número do assento a reservar (inteiro).
Observe como as exceções verificadas obrigam os chamadores a tratá-las (com try-catch ou throws), enquanto as exceções não verificadas não exigem tratamento explícito. Escolha o tipo de exceção com base no fato de o erro ser algo que os chamadores devem antecipar e do qual devem se recuperar!
Experimente você mesmo
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: Crie um TicketBooth com o total de assentos fornecido
// TODO: Use um bloco try-catch para tentar reservar o assento
// - Capture TicketSoldOutException primeiro e imprima "Booking failed: [exception message]"
// - Capture InvalidSeatException e imprima "Booking failed: [exception message]"
// TODO: After the try-catch, print "Remaining seats: [count]"
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada10Tratamento de Exceções em POO
Hierarquia de Classes de ExceçãoExceções PersonalizadasErros Checked vs UncheckedPadrão Try With ResourcesRecapitulação - Usuário Validado2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online