Integração de Tratamento de Exceções
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 82 de 87.
Desafio
FácilVamos tornar seu Sistema de Gerenciamento de Biblioteca mais robusto integrando um tratamento adequado de exceções! Um sistema de biblioteca real precisa lidar elegantemente com condições de erro: o que acontece quando alguém tenta pegar emprestado um livro que não existe ou quando um usuário tenta pegar emprestados mais livros do que o permitido? Você criará exceções personalizadas que fornecem informações significativas para esses cenários.
Você continuará desenvolvendo seu código existente em seis arquivos:
Book.java: Mantenha sua classe Book com todas as funcionalidades existentes: isbn, title, author, isAvailable, borrowedBy, getDetails() e os getters/setters apropriados.User.java: Mantenha sua classe User com id, name, o ArrayList borrowedBooks, borrowBook(), returnBook(), getBorrowedCount() e toString().LibraryException.java: Crie uma classe de exceção personalizada base chamadaLibraryExceptionque estendaException. Essa será a classe pai de todas as exceções específicas da biblioteca. Inclua um construtor que aceite uma mensagem e a passe para a classe pai.BookNotAvailableException.java: Crie uma exceção personalizada que estendaLibraryException. Essa exceção deve ser lançada quando alguém tentar pegar emprestado um livro que já foi emprestado. Inclua um construtor que aceite o ISBN do livro e crie uma mensagem significativa comoBook not available: [isbn].Library.java: Atualize sua classe Library para lançar exceções em vez de imprimir mensagens de erro. Modifique o métodoborrowBook(String userId, String isbn)para:- Lançar
LibraryExceptioncom a mensagemUser not found: [userId]se o usuário não existir - Lançar
LibraryExceptioncom a mensagemBook not found: [isbn]se o livro não existir - Lançar
BookNotAvailableExceptionse o livro já tiver sido emprestado - Em caso de sucesso, fazer com que o usuário pegue o livro emprestado e retornar a mensagem de confirmação
[userName] borrowed [bookTitle]
Altere a assinatura do método para
throws LibraryExceptione altere o tipo de retorno paraString.Mantenha todos os outros métodos (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) funcionando como antes.
- Lançar
Main.java: Demonstre seu tratamento de exceções! Você receberá uma string de comandos separados por vírgulas. Cada comando segue um destes formatos:ADD_BOOK:isbn:title:authorREGISTER_USER:id:nameBORROW:userId:isbn
Processe cada comando. Para ADD_BOOK, imprima
Added: [title]. Para REGISTER_USER, imprimaRegistered: [name]. Para comandos BORROW, use um bloco try-catch para tratar as exceções; em caso de sucesso, imprima a mensagem de confirmação; para qualquerLibraryException, imprimaError: [exception message].Depois de processar todos os comandos, imprima
Operations completed.
Você receberá uma entrada: uma string de comandos separados por vírgulas.
Por exemplo, com a entrada ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001, sua saída seria:
Added: Clean Code
Registered: Alice
Alice borrowed Clean Code
Error: Book not available: ISBN-001
Error: User not found: U002
Operations completedObserve como as exceções personalizadas fornecem mensagens de erro claras e específicas. O primeiro empréstimo é bem-sucedido, o segundo falha porque o livro já foi emprestado (BookNotAvailableException) e o terceiro falha porque o usuário U002 não existe (LibraryException). Essa abordagem torna seu sistema de biblioteca muito mais informativo e fácil de depurar do que mensagens de erro genéricas!
Experimente você mesmo
import java.util.Scanner;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler os comandos separados por vírgula
String input = scanner.nextLine();
String[] commands = input.split(",");
// Criar Library e AdminService
Library library = new Library();
AdminService adminService = new AdminService(library);
// Processar cada comando
for (String command : commands) {
String[] parts = command.split(":");
String operation = parts[0];
if (operation.equals("ADD_BOOK")) {
String isbn = parts[1];
String title = parts[2];
String author = parts[3];
if (adminService.addBook(isbn, title, author)) {
System.out.println("Added: " + title);
}
} else if (operation.equals("REMOVE_BOOK")) {
String isbn = parts[1];
if (adminService.removeBook(isbn)) {
System.out.println("Removed: " + isbn);
} else {
System.out.println("Cannot remove: " + isbn);
}
} else if (operation.equals("REGISTER_USER")) {
String id = parts[1];
String name = parts[2];
if (adminService.registerUser(id, name)) {
System.out.println("Registered: " + name);
}
} else if (operation.equals("BORROW")) {
String userId = parts[1];
String isbn = parts[2];
// TODO: Use um bloco try-catch para chamar library.borrowBook(userId, isbn)
// Em caso de sucesso, imprima a mensagem de confirmação retornada
// Em caso de LibraryException, imprima "Error: " + e.getMessage()
}
}
// TODO: Print "Operations completed"
}
}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 Validado13Projeto: Gerenciamento de Biblioteca
Visão Geral do Projeto e Modelagem UMLClasses Livro e UsuárioSistema de EmpréstimosFuncionalidade de BuscaInterface do AdministradorIntegração de Tratamento de ExceçõesTestes e Integração2Modificadores 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