Introdução: Por que o tratamento de erros em Java é uma arte
\nO tratamento de erros em Java não é apenas um mecanismo para evitar a falha do programa. É uma ferramenta para projetar uma arquitetura robusta, legível e previsível. Todo desenvolvedor conhece a construção try/catch, mas em um nível avançado é importante entender as nuances: quando usar exceções verificadas, como fechar recursos corretamente e por que o multi-catch pode evitar a duplicação de código. Neste artigo, abordaremos técnicas avançadas de trabalho com exceções em Java que o ajudarão a escrever um código mais limpo e seguro.
1. Multi-catch e combinação de exceções
\nAntes do Java 7, tratar diferentes tipos de exceções em um único bloco catch era impossível. Era necessário duplicar o código ou usar uma classe pai comum (por exemplo, Exception), o que reduzia a informatividade do erro. Com o surgimento do multi-catch, a situação mudou.
Sintaxe do multi-catch
\nVocê pode listar vários tipos de exceções separados por uma barra vertical (|) em um único bloco catch. Isso é útil quando a lógica de tratamento para diferentes exceções é idêntica.
try {\n // Código que pode lançar FileNotFoundException ou IOException\n FileReader reader = new FileReader("file.txt");\n int data = reader.read();\n} catch (FileNotFoundException | IOException e) {\n System.err.println("Erro de entrada/saída: " + e.getMessage());\n}\nImportante: a variável e em tal bloco é final (ou effectively final). Isso significa que ela não pode ser reatribuída, mas métodos da superclasse comum (por exemplo, getMessage()) podem ser chamados.
Quando usar multi-catch?
\n- \n
- Se as exceções não estão relacionadas por hierarquia (por exemplo,
IOExceptioneSQLException). \n - Se a lógica de tratamento for completamente idêntica. \n
- Se você quiser evitar a duplicação de blocos
catch. \n
2. Try-with-resources: gerenciamento automático de recursos
\nUm dos erros mais comuns em Java é esquecer de fechar um recurso (arquivo, socket, conexão com banco de dados). O fechamento manual em um bloco finally leva a um código verboso e ao risco de vazamento. A construção try-with-resources (Java 7+) resolve esse problema.
Como funciona
\nO recurso deve implementar a interface AutoCloseable (ou Closeable). Após a conclusão do bloco try (ou na ocorrência de uma exceção), o recurso será fechado automaticamente.
try (FileReader reader = new FileReader("file.txt");\n BufferedReader br = new BufferedReader(reader)) {\n String line = br.readLine();\n System.out.println(line);\n} catch (IOException e) {\n System.err.println("Erro: " + e.getMessage());\n}\n// reader e br são fechados automaticamente\nRecursos avançados
\n- \n
- Múltiplos recursos: podem ser declarados separados por ponto e vírgula. O fechamento ocorre na ordem inversa. \n
- Exceções suprimidas: se uma exceção for lançada ao fechar o recurso, mas a exceção principal já tiver sido lançada, o Java "suprime" a exceção de fechamento. Ela pode ser obtida através do método
getSuppressed(). \n - Uso com recursos personalizados: qualquer classe que implemente
AutoCloseablepode ser usada emtry-with-resources. \n
3. Criação de exceções personalizadas e best practices
\nAs exceções integradas do Java muitas vezes não são suficientes para a lógica de negócios. Criar suas próprias classes de exceção é uma prática padrão. No entanto, é importante fazer isso corretamente.
\nExceções verificadas vs. não verificadas
\nSiga uma regra simples: se a exceção pode ser tratada pelo cliente (por exemplo, formato inválido de dados de entrada), torne-a verificada (herde de Exception). Se a exceção indicar um erro de programação (por exemplo, passar um argumento nulo onde não é permitido), use uma exceção não verificada (herde de RuntimeException).
\n\n