Tratamento de Erros em Java: try/catch e muito mais: do A ao Z
O tratamento de erros é um dos conceitos-chave em Java que todo desenvolvedor deve dominar. Ao contrário de muitas linguagens, o Java oferece um sistema de exceções (exceptions) rigoroso e bem elaborado, que permite escrever código confiável e previsível. Neste artigo, abordaremos tudo: desde o básico try/catch até mecanismos avançados, como try-with-resources e exceções personalizadas.
1. Fundamentos: o que são exceções e a hierarquia de classes
Uma exceção (exception) é um evento que interrompe o fluxo normal de execução de um programa. Em Java, todas as exceções são objetos de classes que herdam de Throwable. Os principais ramos da hierarquia são:
- Error — problemas críticos que geralmente não são tratados (por exemplo,
OutOfMemoryError). - Exception — exceções que o programa pode tratar.
- RuntimeException (subclasse de Exception) — exceções de tempo de execução que não precisam ser verificadas em tempo de compilação.
Todas as exceções são divididas em dois tipos:
- Checked (verificadas) — obrigatórias de tratar. O compilador não permitirá compilar o código se você não as tratar com
try/catchou não as declarar comthrows. Exemplos:IOException,SQLException. - Unchecked (não verificadas) — herdam de
RuntimeException. Não precisam ser tratadas explicitamente. Exemplos:NullPointerException,ArithmeticException.
2. Mecanismo básico: try, catch, finally
O bloco básico de tratamento de exceções consiste em três partes:
try { // Código que pode lançar uma exceção int result = 10 / 0;} catch (ArithmeticException e) { // Tratamento da exceção System.err.println("Erro: divisão por zero!");} finally { // Este bloco é executado sempre (mesmo se houve exceção) System.out.println("Bloco finally executado.");}Pontos importantes:
- O bloco
catchpode ser um ou vários para diferentes tipos de exceções. - O bloco
finallyé opcional, mas útil para fechar recursos (arquivos, conexões). - Se a exceção não for capturada, ela é propagada para cima na pilha de chamadas.
Multi-catch (Java 7+) — permite capturar vários tipos de exceções em um único bloco:
try { // código} catch (IOException | SQLException e) { System.err.println("Erro de E/S ou SQL: " + e.getMessage());}3. Try-with-resources: fechamento automático de recursos
A partir do Java 7, surgiu o mecanismo try-with-resources, que fecha automaticamente recursos que implementam a interface AutoCloseable (ou Closeable). Isso elimina a necessidade de escrever finally para fechar arquivos, sockets, etc.
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) { String line = reader.readLine(); System.out.println(line);} catch (IOException e) { System.err.println("Erro ao ler arquivo: " + e.getMessage());} // reader é fechado automaticamenteVantagens:
- O código fica mais limpo e curto.
- Os recursos são fechados na ordem correta (ordem inversa da sua criação).
- Se uma exceção for lançada tanto no bloco try quanto no fechamento, a exceção suprimida (suppressed) é adicionada à principal.
Você pode declarar vários recursos separados por ponto e vírgula:
try (BufferedReader br = new BufferedReader(new FileReader("in.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"))) { // código} catch (IOException e) { System.err.println("Erro de E/S: " + e.getMessage());}