Por que eu devo ler este artigo:Este artigo apresenta em detalhes como é realizado o tratamento de exceções na linguagem Java. Para isso, com exemplos, abordaremos os mecanismos que podem ser empregados para o controle de erros, mecanismos estes que simplificam o trabalho do programador no tratamento das diferentes condições adversas que ocorrem no decorrer da implementação de programas.

Além disso, veremos como é possível criar exceções customizadas, voltadas para necessidades específicas de acordo com as regras de negócio definidas na aplicação.

Uma exceção é um problema (erro) que ocorre durante a execução de um programa. Como sabemos, em qualquer programa de computador existem diversos motivos para a ocorrência de erros. Alguns dos mais comuns são destacados a seguir:

  • O usuário entrou com dados inválidos na aplicação;
  • Um arquivo não foi encontrado no momento da sua abertura;
  • Foi acessado um arquivo que está em branco e era esperado que tivesse conteúdo;
  • Erro de conversão de String para float, devido ao formato numérico incompatível;
  • Queda de conexão com a internet durante a transmissão de dados por uma stream;
  • Divisão de um número por zero.

A exceção, de modo simples, pode ser entendida como uma forma comum de informar a ocorrência de uma condição anormal no programa, ou seja, uma situação de erro. Quando acontece um problema em um método e o mesmo não pode resolver sozinho, ele pode lançar uma exceção, sinalizando e descrevendo o erro. Consequentemente, essa exceção pode receber tratamento próprio em outro ponto do programa. Entretanto, caso não seja tratada, o programa finalizará prematuramente e o método main() imprimirá um resumo da exceção na tela.

Como você poderá constatar, muitas linguagens de programação não apresentam o tratamento de exceções nativamente. Portanto, cada método ou função precisa disponibilizar algum tipo de tratamento, o que aumenta a complexidade da tarefa de codificação, pois são usados códigos de erros distintos, retornos nulos, flags e outras situações, sem haver um padrão. Por outro lado, o Java oferece uma abordagem simplificada, permitindo tratar qualquer tipo de ocorrência de erro através de uma hierarquia de classes de erros, onde a principal é a classe Exception. Ademais, permite ao programador definir novos tipos de exceção, customizados, que podem ser usados pela aplicação.

Como veremos no decorrer do artigo, o principal objetivo do gerenciamento de exceções é, no momento de um erro, transferir o controle do programa para um trecho de código que possa lidar com a exceção, realizando o tratamento do mesmo de forma conveniente. O código responsável por esse “reparo” é chamado de tratador de exceção (exception handler), visto que oferece uma solução para o erro ocorrido. Assim, durante a atividade de programação em Java, deve-se posicionar tratadores de exceção “estrategicamente” no código para que o programa possa capturar e resolver qualquer exceção passível de ser lançada, evitando o encerramento inesperado do aplicativo.

Resposta a uma exceção

Considerando a ocorrência de uma exceção em um programa, o mesmo pode tratá-la de diferentes formas. A seguir analisamos as opções:

  • Ignorar a exceção: Dessa forma, o programa terminará anormalmente ou produzirá resultados incorretos;
  • Atribuir a resolução do problema ao usuário: Como o usuário não é programador, é muito provável que ele não saberá solucionar o problema;
  • Tratar o erro no programa: O programador desenvolve a aplicação de forma que, quando o erro ocorrer, é acionado um bloco de código responsável pelo tratamento do erro.

É claro que a melhor solução é fazer o programa tratar a exceção, e se não houver uma solução disponível, deve-se notificar o usuário do ocorrido para que ele possa tomar alguma atitude. Por exemplo, em uma aplicação de uma grande corporação, na ocorrência de erros, é importante mostrar para o usuário uma mensagem apropriada, oferecendo possíveis soluções. Caso o erro não seja reparável, a sua ocorrência pode ser armazenada em um registro para consulta futura.

A hierarquia de classes das exceções

Como em tudo em Java, criar uma exceção significa criar um objeto. Portanto, quando um programa lança uma exceção, ele está lançando um objeto, derivado de qualquer subclasse de Throwable, a classe mais alta na hierarquia das exceções. Throwable representa qualquer tipo de erro que pode acontecer em uma aplicação e se divide em duas categorias: Exception e Error.

A superclasse da maioria das exceções é a classe Exception. Esta sinaliza a ocorrência de erros comuns, que podem acontecer em qualquer aplicação, e está relacionada a erros que podem ser resolvidos com o devido tratamento, como um arquivo não encontrado, um arquivo em branco, divisão por zero, conversão inválida de classe, acesso a ponteiro nulo, conversão numérica inválida, fechamento inesperado de uma stream de dados, etc.

Por outro lado, Error indica um tipo mais rigoroso de erro, onde geralmente não é possível tratá-lo e nem continuar a execução do programa. Enquadram-se nessa categoria os erros de falta de memória, classe não encontrada, classe inválida, erro interno da máquina virtual, etc.

Ao lançar uma exceção em Java é criada uma instância de uma subclasse de Throwable, como Exception, Error ou suas subclasses. Cada tipo de exceção tem um papel específico, sendo necessário apenas instanciar e lançar a exceção do tipo correto (a que corresponde ao erro ocorrido). Uma parte da hierarquia de classes de exceções pode ser verificada na Figura 1.

Hierarquia de exceções da linguagem Java

Figura 1. Hierarquia de exceções da linguagem Java.

A classe Throwable

Com relação à classe Throwable, somente seus objetos (ou subclasses de Throwable) podem ser lançados pela máquina virtual Java na ocorrência de erros ou pelo programador, usando o comando throw. Os principais construtores da classe Throwable são:

  • public Throwable(): Constrói um objeto Throwable sem mensagem de erro;
  • public Throwable(String mensagem): Constrói um objeto Throwable com a mensagem de erro informada por parâmetro.

Além disso, a classe Throwable possui uma série de métodos auxiliares, que são herdados pelas suas subclasses. São eles:

  • public String getMessage( ...
    Quer ler esse conteúdo completo? Tenha acesso completo