10 Tratamento de erros e arquivos
Recuperar entradas inválidas e persistir o histórico
10.1 Objetivos de aprendizagem
Ao concluir este capítulo, você deverá ser capaz de:
- distinguir erro de compilação, exceção e erro de lógica;
- capturar apenas exceções que podem ser tratadas naquele ponto;
- repetir a leitura até obter uma entrada válida;
- lançar
IllegalArgumentExceptionpara contratos violados; - salvar texto em arquivo com tratamento de
IOException.
10.2 Exceções esperadas
Em programas interativos, entradas inválidas são previsíveis. Integer.parseInt lança NumberFormatException quando o texto não representa um inteiro:
Não capture Exception sem necessidade. Um tipo específico documenta o cenário esperado e evita esconder defeitos diferentes.
10.3 Repetir até obter um valor válido
import java.util.Scanner;
static int lerInteiro(Scanner scanner, String mensagem) {
while (true) {
System.out.print(mensagem);
String entrada = scanner.nextLine();
try {
return Integer.parseInt(entrada);
} catch (NumberFormatException erro) {
System.out.println("Valor inválido. Tente novamente.");
}
}
}A leitura e a recuperação ficam centralizadas. O restante do programa recebe um inteiro válido.
10.4 Lançar uma exceção
Use uma exceção quando o chamador viola o contrato de um método:
Capturar ou propagar depende da responsabilidade. A interface de console pode capturar e mostrar uma orientação; uma classe de domínio normalmente lança a exceção e deixa a decisão para a camada externa.
10.5 Persistência com try-with-resources
A API Files simplifica a escrita de linhas e gerencia o fechamento do arquivo:
No limite externo do programa, trate a falha:
A mensagem para a pessoa usuária é curta; o detalhe técnico vai para o fluxo de erro.
10.6 Exemplo completo
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class Capitulo09ErrosArquivos {
public static void salvarHistorico(Path arquivo, List<String> linhas)
throws IOException {
Files.write(arquivo, linhas);
}
public static void main(String[] args) {
List<String> historico = List.of("USUÁRIO: oi", "BOT: Olá!");
try {
salvarHistorico(Path.of("historico.txt"), historico);
System.out.println("Histórico salvo.");
} catch (IOException erro) {
System.out.println("Não foi possível salvar o histórico.");
System.err.println(erro.getMessage());
}
}
}10.7 Evolução do projeto: versão 9
O chatbot recupera entradas numéricas inválidas e oferece a opção de salvar o histórico ao encerrar. A falha de escrita não destrói a conversa nem mostra uma pilha de exceção para a pessoa usuária.
O exemplo completo está em examples/src/Capitulo09ErrosArquivos.java.
10.8 Prática verificável
- Leia uma idade até receber valor numérico entre 0 e 130.
- Salve três mensagens em
historico.txt. - Teste um caminho de arquivo inválido e confirme a mensagem amigável.
- Explique por que
NumberFormatExceptioneIOExceptionsão tratadas em lugares diferentes.
Condições simples, como texto vazio, devem ser verificadas diretamente. Exceções são apropriadas quando uma operação não consegue cumprir seu contrato.