Tratamento de Exceções

Aprenda a lidar com erros de forma elegante e robusta

Exceções Java

Tratamento de Exceções em Java

O tratamento de exceções é um mecanismo fundamental em Java que permite lidar com erros e situações excepcionais de forma controlada e elegante. Um bom tratamento de exceções torna as aplicações mais robustas e confiáveis.

O que são Exceções?

Uma exceção é um evento que ocorre durante a execução de um programa e interrompe o fluxo normal das instruções. Em Java, exceções são objetos que representam condições de erro ou situações excepcionais que podem ocorrer durante a execução do programa.

Hierarquia de Exceções

Em Java, todas as exceções herdam da classe Throwable, que possui duas subclasses principais:

1. Error

Representa erros graves do sistema que geralmente não devem ser capturados pela aplicação, como OutOfMemoryError ou StackOverflowError.

2. Exception

Representa condições excepcionais que uma aplicação pode querer capturar e tratar. Divide-se em:

  • Checked Exceptions: Devem ser tratadas ou declaradas (IOException, SQLException)
  • Unchecked Exceptions (RuntimeException): Não precisam ser tratadas obrigatoriamente (NullPointerException, ArrayIndexOutOfBoundsException)

Try-Catch-Finally

A estrutura try-catch-finally é o mecanismo principal para tratamento de exceções em Java:

Bloco Try

Contém o código que pode gerar uma exceção. É onde colocamos o código "arriscado" que queremos monitorar.

Bloco Catch

Captura e trata exceções específicas. Pode haver múltiplos blocos catch para diferentes tipos de exceções.

Bloco Finally

Executa sempre, independentemente de uma exceção ter sido lançada ou não. É usado para limpeza de recursos como fechamento de arquivos ou conexões de banco de dados.

Tipos Comuns de Exceções

NullPointerException

Ocorre quando tentamos acessar um método ou propriedade de um objeto que é null. É uma das exceções mais comuns em Java.

ArrayIndexOutOfBoundsException

Lançada quando tentamos acessar um índice inválido de um array (menor que 0 ou maior que o tamanho do array).

NumberFormatException

Ocorre quando tentamos converter uma string para um número, mas a string não representa um número válido.

IOException

Exceção checked que ocorre durante operações de entrada/saída, como leitura de arquivos ou comunicação de rede.

SQLException

Exceção checked relacionada a operações de banco de dados.

Throws e Throw

Throws

A palavra-chave throws é usada na assinatura de um método para declarar que ele pode lançar determinadas exceções. Isso transfere a responsabilidade de tratamento para quem chama o método.

Throw

A palavra-chave throw é usada para lançar explicitamente uma exceção. Pode ser usada para lançar exceções predefinidas ou customizadas.

Try-with-Resources

Introduzido no Java 7, o try-with-resources é uma forma elegante de garantir que recursos sejam fechados automaticamente. Qualquer objeto que implemente AutoCloseable pode ser usado.

Exceções Customizadas

Você pode criar suas próprias exceções estendendo Exception (checked) ou RuntimeException (unchecked). Isso permite criar exceções específicas para seu domínio de aplicação.

Multi-Catch

A partir do Java 7, é possível capturar múltiplas exceções em um único bloco catch usando o operador pipe (|). Isso reduz duplicação de código quando o tratamento é o mesmo para diferentes exceções.

Boas Práticas

1. Seja Específico

Capture exceções específicas em vez de usar Exception genérica. Isso permite tratamento mais adequado para cada tipo de erro.

2. Não Ignore Exceções

Nunca deixe um bloco catch vazio. Pelo menos registre a exceção em logs para facilitar a depuração.

3. Use Finally para Limpeza

Sempre feche recursos como arquivos, conexões de banco de dados e streams no bloco finally ou use try-with-resources.

4. Falhe Rapidamente

Valide parâmetros no início dos métodos e lance exceções imediatamente se algo estiver errado.

5. Documente Exceções

Use @throws na documentação Javadoc para documentar que exceções um método pode lançar.

6. Prefira Unchecked para Erros de Programação

Use RuntimeException para erros que indicam bugs no código, como argumentos inválidos.

7. Use Checked para Condições Recuperáveis

Use Exception para condições que o cliente pode razoavelmente esperar recuperar.

Logging de Exceções

É fundamental registrar exceções adequadamente para facilitar a manutenção e depuração. Use frameworks de logging como SLF4J com Logback ou Log4j para registrar exceções com diferentes níveis de severidade.

Performance e Exceções

Exceções têm custo computacional significativo porque capturam o stack trace. Evite usar exceções para controle de fluxo normal do programa. Reserve-as para situações verdadeiramente excepcionais.

Exceções em Threads

Exceções não tratadas em threads podem causar o término abrupto da thread. Use UncaughtExceptionHandler para capturar exceções não tratadas em threads.

Testando Exceções

Em testes unitários, use anotações como @Test(expected = ExceptionClass.class) no JUnit 4 ou assertThrows() no JUnit 5 para verificar se exceções são lançadas corretamente.