Lista 08#
Questão 1#
Tópicos: checked e unchecked exceptions, try/catch/finally, try-with-resources, exceções personalizadas, encadeamento.
Você está desenvolvendo um programa que lê um arquivo CSV contendo dados de alunos e valida cada registro. O arquivo tem o formato nome;idade;nota (uma linha por aluno). Exemplo de conteúdo:
Ana;20;8.5
Bruno;abc;7.0
;25;9.0
Carlos;17;11.5
Diana;22;6.0Crie uma exceção checked chamada
RegistroInvalidoExceptionque:- Possua um atributo
int numeroLinhae um métodogetNumeroLinha(). - Aceite no construtor: mensagem, número da linha e, opcionalmente, uma causa (
Throwable) para permitir encadeamento.
- Possua um atributo
Crie uma classe
ProcessadorDeAlunoscom o método:public void processar(String caminhoArquivo) throws RegistroInvalidoExceptionEsse método deve:
- Abrir o arquivo com
try-with-resources(usandoBufferedReader). - Ler cada linha e separar os campos por
";". - Para cada linha, validar:
- Se o nome estiver vazio, lançar
RegistroInvalidoExceptioncom a mensagem"Nome vazio na linha <n>". - Converter a idade com
Integer.parseInt(). Se falhar, capturar oNumberFormatExceptione lançarRegistroInvalidoExceptioncom a mensagem"Idade inválida na linha <n>", encadeando oNumberFormatExceptioncomo causa. - Converter a nota com
Double.parseDouble(). Se o valor estiver fora do intervalo 0–10, lançarRegistroInvalidoExceptioncom a mensagem"Nota fora do intervalo na linha <n>".
- Se o nome estiver vazio, lançar
- Se a linha for válida, exibir:
"Aluno registrado: <nome>, idade <idade>, nota <nota>". - Importante: ao encontrar o primeiro registro inválido, o método deve lançar a exceção imediatamente (não continue processando as linhas seguintes).
- Abrir o arquivo com
Na classe
Main:- Chame
processardentro de umtry/catchque trateRegistroInvalidoException, exibindo:- A mensagem de erro.
- O número da linha.
- A causa (
getCause()), se existir.
- Use um bloco
finallypara exibir"Processamento encerrado.".
- Chame
Exemplo de saída esperada (usando o CSV de exemplo acima):
Aluno registrado: Ana, idade 20, nota 8.5
Erro no registro — Idade inválida na linha 2
Causa: java.lang.NumberFormatException: For input string: "abc"
Processamento encerrado.Questão 2#
Implemente um sistema simplificado de autenticação de usuários.
Crie uma exceção checked chamada
AutenticacaoExceptionque receba uma mensagem no construtor.Crie uma classe
ServicoDeLogincom:- Um atributo
Map<String, String>inicializado diretamente no código com pelo menos 3 pares de login/senha (por exemplo:"admin"/"1234","maria"/"abcd","joao"/"xyz9"). - Um método
autenticar(String login, String senha) throws AutenticacaoExceptionque:- Lance
AutenticacaoExceptioncom a mensagem"Usuário não encontrado"se o login não existir no mapa. - Lance
AutenticacaoExceptioncom a mensagem"Senha incorreta"se o login existir mas a senha não corresponder. - Retorne a mensagem
"Bem-vindo, <login>!"se as credenciais estiverem corretas.
- Lance
- Um atributo
Na classe
Main:- Leia login e senha do usuário via
Scanner. - Chame o método
autenticare exiba o retorno em caso de sucesso. - Trate
AutenticacaoExceptionexibindo a mensagem de erro. - Utilize um bloco
finallypara fechar oScannere exibir"Conexão encerrada.".
- Leia login e senha do usuário via
Exemplos de execução:
Login: admin
Senha: 1234
Bem-vindo, admin!
Conexão encerrada.Login: admin
Senha: errada
Erro: Senha incorreta
Conexão encerrada.Login: carlos
Senha: 1234
Erro: Usuário não encontrado
Conexão encerrada.Questão 3#
Você está criando um módulo que recebe notas digitadas como texto (String) e as converte para valores numéricos, aplicando regras de validação.
Crie uma exceção checked chamada
NotaForaDeIntervaloExceptionque:- Estenda
Exception. - Possua um atributo
double notacom o valor que causou o erro. - Forneça um método
getNota(). - Receba a nota e uma mensagem no construtor.
- Estenda
Crie uma classe
ConversorDeNotascom o método:public double converter(String entrada) throws NotaForaDeIntervaloExceptionEsse método deve:
- Converter a String para
doubleusandoDouble.parseDouble(). Se a entrada não for um número válido, umNumberFormatException(que é unchecked) será lançado naturalmente — não trate essa exceção aqui; deixe-a propagar. - Se o valor convertido for menor que 0 ou maior que 10, lance
NotaForaDeIntervaloExceptioncom a mensagem"Nota fora do intervalo permitido (0 a 10)". - Caso contrário, retorne o valor convertido.
- Converter a String para
Na classe
Main, leia 5 notas do usuário viaScanner(como Strings) e, para cada uma, chameconverterdentro de um blocotry/catchque trate:NotaForaDeIntervaloException— exibindo a mensagem e o valor da nota inválida.NumberFormatException— exibindo"Entrada inválida: '<entrada>' não é um número.".
Ao final, exiba a média das notas que foram convertidas com sucesso. Se nenhuma nota for válida, exiba
"Nenhuma nota válida foi informada.".
Exemplo de execução:
Digite a nota 1: 8.5
Nota registrada: 8.5
Digite a nota 2: abc
Entrada inválida: 'abc' não é um número.
Digite a nota 3: 11
Nota fora do intervalo permitido (0 a 10). Valor informado: 11.0
Digite a nota 4: 7
Nota registrada: 7.0
Digite a nota 5: -2
Nota fora do intervalo permitido (0 a 10). Valor informado: -2.0
Média das notas válidas: 7.75Questão 4#
Implemente um gerenciador simples de tarefas com controle de prazos.
Crie duas exceções personalizadas:
TarefaInvalidaException— unchecked (estendeRuntimeException). Será usada para erros de dados da tarefa (título nulo/vazio, prazo nulo).PrazoExpiradoException— checked (estendeException). Será usada quando uma tarefa for marcada como concluída após o prazo. Deve possuir um atributoLocalDate prazoe um métodogetPrazo().
Crie uma classe
Tarefacom:- Atributos:
String titulo,LocalDate prazo,boolean concluida. - No construtor
Tarefa(String titulo, LocalDate prazo):- Se
titulofornullou vazio, lanceTarefaInvalidaExceptioncom a mensagem"O título da tarefa não pode ser nulo ou vazio". - Se
prazofornull, lanceTarefaInvalidaExceptioncom a mensagem"O prazo da tarefa não pode ser nulo".
- Se
- Um método
concluir() throws PrazoExpiradoExceptionque:- Marca a tarefa como concluída (
concluida = true). - Se
LocalDate.now()for posterior ao prazo, lancePrazoExpiradoExceptioncom a mensagem"A tarefa '<titulo>' foi concluída após o prazo", passando o prazo.
- Marca a tarefa como concluída (
- Atributos:
Na classe
Main:- Crie 3 tarefas dentro de um bloco
try/catch:- Uma com título válido e prazo futuro.
- Uma com título vazio (para disparar
TarefaInvalidaException). - Uma com título válido e prazo no passado.
- Observe que a criação da tarefa com título vazio lança uma exceção unchecked, que pode ser tratada no
catchmas não é obrigatória. - Para cada tarefa criada com sucesso, chame
concluir()dentro de seu próprio blocotry/catchpara tratarPrazoExpiradoException. - Use um bloco
finallyao final de cada tentativa de conclusão para exibir o status da tarefa:"Tarefa '<titulo>' - Concluída: <true/false>".
- Crie 3 tarefas dentro de um bloco
Exemplo de saída esperada:
Criando tarefa: Estudar exceções... OK
Criando tarefa com título vazio... Erro: O título da tarefa não pode ser nulo ou vazio
Criando tarefa: Entregar relatório... OK
Concluindo tarefa: Estudar exceções...
Tarefa concluída com sucesso.
Tarefa 'Estudar exceções' - Concluída: true
Concluindo tarefa: Entregar relatório...
Erro: A tarefa 'Entregar relatório' foi concluída após o prazo (prazo: 2025-01-15)
Tarefa 'Entregar relatório' - Concluída: trueQuestão 5#
Um professor deseja um programa que leia a nota de um aluno pelo teclado (usando Scanner) e exiba o conceito correspondente:
| Faixa | Conceito |
|---|---|
| 9,0 – 10,0 | A |
| 7,0 – 8,9 | B |
| 5,0 – 6,9 | C |
| < 5,0 | D |
- Crie uma classe
ConversorDeNotascom um métodoobterConceito(double nota)que:- Lance
IllegalArgumentExceptioncaso a nota seja menor que 0 ou maior que 10. - Retorne o conceito (
String) correspondente à nota.
- Lance
- No método
main, useScannerpara ler a nota digitada pelo usuário e chameobterConceito. O código deve conter:- Um bloco
tryenvolvendo a leitura e a chamada ao método. - Um bloco
catchparaInputMismatchException(caso o usuário digite algo que não seja número). - Um bloco
catchparaIllegalArgumentException(caso a nota esteja fora da faixa válida). - Uma mensagem de erro adequada em cada bloco
catch, seguida de uma ação útil (por exemplo, solicitar nova entrada ao usuário em vez de apenas imprimir o erro).
- Um bloco
- Coloque a lógica dentro de um laço que permita ao usuário tentar novamente até fornecer uma entrada válida.
Questão 6#
Um arquivo chamado alunos.csv contém dados de alunos no seguinte formato (um aluno por linha):
nome;nota1;nota2;nota3
Ana;8.5;7.0;9.0
Bruno;5.0;4.5;6.0
Carla;10.0;9.5;8.0- Crie um método
gerarRelatorio(String caminhoEntrada, String caminhoSaida)que:- Leia o arquivo CSV linha a linha.
- Calcule a média das três notas de cada aluno.
- Escreva em um arquivo de saída (
relatorio.txt) o nome do aluno e sua média, no formato:Ana - Média: 8.17.
- Implemente duas versões desse método:
- Versão A — com
finally: abraFileReader/BufferedReadereFileWriter/BufferedWriterantes dotry, e feche-os explicitamente no blocofinally. - Versão B — com
try-with-resources: declare os recursos dentro dotry(...), eliminando a necessidade dofinally.
- Versão A — com
- Em ambas as versões, trate
FileNotFoundException(arquivo de entrada inexistente) eIOException(erro durante leitura/escrita) com mensagens descritivas. - No
main, chame ambas as versões e observe o comportamento quando o arquivo de entrada não existe.
Questão 7#
Considere um sistema simplificado de agendamento de serviços em uma oficina mecânica. A oficina possui horários disponíveis (por exemplo, "08:00", "10:00", "14:00", "16:00") e cada horário só pode ser ocupado por um cliente.
Crie duas exceções personalizadas (checked):
HorarioIndisponivelException— lançada quando o cliente tenta agendar um horário que já está ocupado. Deve armazenar o horário solicitado.AgendamentoInvalidoException— lançada quando o horário informado não existe na lista de horários da oficina. Deve armazenar o horário inválido.
Ambas devem estender
Exceptione possuir construtores que recebam uma mensagem descritiva e o horário.Crie uma classe
Agendacom:- Um
Map<String, String>que associa horários a nomes de clientes (valornullsignifica horário livre). - Um método
agendar(String horario, String cliente) throws HorarioIndisponivelException, AgendamentoInvalidoExceptionque:- Lance
AgendamentoInvalidoExceptionse o horário não estiver na lista. - Lance
HorarioIndisponivelExceptionse o horário já estiver ocupado, informando qual cliente já ocupa aquele horário. - Caso contrário, registre o agendamento.
- Lance
- Um método
listarAgendamentos()que exiba todos os horários e seus respectivos clientes.
- Um
No
main, simule as seguintes situações, tratando cada exceção comtry/catch:- Agendar um horário válido e livre.
- Tentar agendar um horário que já está ocupado.
- Tentar agendar um horário que não existe (por exemplo,
"12:00").
Crie também um método
agendarOuSugerir(String horario, String cliente)que não trate as exceções internamente, mas as declare comthrows, delegando o tratamento ao código chamador.
Questão 8#
Considere um sistema simples de processamento de pagamentos que suporta dois meios: saldo em conta e cartão de crédito.
Crie a seguinte hierarquia de exceções (todas checked):
PagamentoException (extends Exception) ├── SaldoInsuficienteException └── CartaoExpiradoExceptionPagamentoException: exceção base, com construtores que aceitem mensagem e causa (Throwable).SaldoInsuficienteException: deve armazenar o saldo disponível e o valor solicitado.CartaoExpiradoException: deve armazenar a data de validade do cartão.
Crie uma classe
ProcessadorDePagamentocom:- Um método
pagarComSaldo(double valor, double saldoDisponivel) throws SaldoInsuficienteException. - Um método
pagarComCartao(double valor, String validadeCartao) throws CartaoExpiradoException(considere que o cartão está expirado se a validade for anterior ao mês/ano atual; useYearMonthpara a comparação). - Um método
realizarPagamento(double valor, String meio, double saldo, String validade) throws PagamentoExceptionque:- Chame o método de pagamento apropriado com base no
meio("saldo"ou"cartao"). - Caso uma exceção seja lançada pelos métodos internos, encapsule-a em uma nova
PagamentoExceptioncom uma mensagem descritiva e a exceção original como causa (exceção encadeada).
- Chame o método de pagamento apropriado com base no
- Um método
No
main, chamerealizarPagamentocom cenários que provoquem cada tipo de erro. Ao capturarPagamentoException, usegetCause()para identificar e exibir a causa original do problema, incluindo os detalhes específicos (saldo disponível, validade do cartão etc.).Para cada exceção capturada, exiba:
- A mensagem da
PagamentoException. - O tipo da causa original (
getCause().getClass().getSimpleName()). - Os detalhes específicos da causa (fazendo cast para o tipo correto).
- A mensagem da