Tratando exceções em Java
Veja neste artigo como tratar exceções na linguagem Java, entendendo a teoria de funcionamento desse tipo de estrutura, passando pelos comandos de tratamento e captura até a customização de exceções para fins específicos.
Quando se cria programas de computador em Java, há possibilidade de ocorrer erros imprevistos durante sua execução, esses erros são conhecidos como exceções e podem ser provenientes de erros de lógica ou acesso a dispositivos ou arquivos externos.
Entendendo as exceções
As exceções ocorrem quando algo imprevisto acontece, elas podem ser provenientes de erros de lógica ou acesso a recursos que talvez não estejam disponíveis.
Alguns possíveis motivos externos para ocorrer uma exceção são:
- Tentar abrir um arquivo que não existe.
- Tentar fazer consulta a um banco de dados que não está disponível.
- Tentar escrever algo em um arquivo sobre o qual não se tem permissão de escrita.
- Tentar conectar em servidor inexistente.
Alguns possíveis erros de lógica para ocorrer uma exceção são:
- Tentar manipular um objeto que está com o valor nulo.
- Dividir um número por zero.
- Tentar manipular um tipo de dado como se fosse outro.
- Tentar utilizar um método ou classe não existentes.
Tratando Exceções
Uma maneira de tentar contornar esses imprevistos é realizar o tratamento dos locais no código que podem vir a lançar possíveis exceções, como por exemplo, campo de consulta a banco de dados, locais em que há divisões, consulta a arquivos de propriedades ou arquivos dentro do próprio computador.
Para tratar as exceções em Java são utilizados os comandos try e catch.
Sintaxe:
try
{
//trecho de código que pode vir a lançar uma exceção
}
catch(tipo_exceçao_1 e)
{
//ação a ser tomada
}
catch(tipo_exceçao_2 e)
{
//ação a ser tomada
}
catch(tipo_exceçao_n e)
{
//ação a ser tomada
}
Onde:
- try{ … } - Neste bloco são introduzidas todas as linhas de código que podem vir a lançar uma exceção.
- catch(tipo_excessao e) { … } - Neste bloco é descrita a ação que ocorrerá quando a exceção for capturada.
Exemplificando uma exceção
Imagine uma classe que tem um método principal main que tem como seu único objetivo alterar todas as letras de um frase para maiúsculas utilizando o método toUpperCase() da classe String, caso a frase esteja nula e se tente usar o método toUpperCase() na mesma será lançada uma exceção de NullPointerException.
Primeiro vamos ver como ficaria a tal classe sem a utilização do try/catch.
public class aumentaFrase {
public static void main(String args[])
{
String frase = null;
String novaFrase = null;
novaFrase = frase.toUpperCase();
System.out.println("Frase antiga: "+frase);
System.out.println("Frase nova: "+novaFrase);
}
}
Quando este código for executado, o mesmo lançará uma NullPointerException, como poder ser visto na saída do console quando executamos tal programa.
Exception in thread "main" java.lang.NullPointerException
at aumentaFrase.main(aumentaFrase.java:15)
Ou seja, o mesmo tentou acessar um atributo de um objeto que estava nulo. Para ajudar a melhorar a situação, deve-se usar o try/catch.
public static void main(String args[])
{
String frase = null;
String novaFrase = null;
try
{
novaFrase = frase.toUpperCase();
}
catch(NullPointerException e) //CAPTURA DA POSSÍVEL exceção.
{
//TRATAMENTO DA exceção
System.out.println("O frase inicial está nula,
para solucional tal o problema, foi lhe atribuito um valor default.");
frase = "Frase vazia";
novaFrase = frase.toUpperCase();
}
System.out.println("Frase antiga: "+frase);
System.out.println("Frase nova: "+novaFrase);
}
Quando este código for executado, o mesmo lançará uma NullPointerException, porém esta exceção será tratada desta vez, sendo a mesma capturada pelo catch{} e dentro deste bloco as devidas providências são tomadas. Neste caso é atribuído um valor default à variável frase. A saída deste programa seria a seguinte:
array4
Comando finally
Imagine a seguinte situação: foi aberta uma conexão com o banco de dados para realizar determinada ação, e no meio deste processo seja lançada alguma exceção, como por exemplo, NullPointerException ao tentar manipular um determinado atributo de um objeto. Neste caso seria necessário que mesmo sendo lançada uma exceção no meio do processo a conexão fosse fechada. Um outro exemplo bom seria a abertura de determinado arquivo para escrita no mesmo, e no meio deste processo é lançada uma exceção por algum motivo, o arquivo não seria fechado, o que resultaria em deixar o arquivo aberto.
Quando uma exceção é lançada e é necessário que determinada ação seja tomada mesmo após a sua captura, utilizamos a palavra reservada finally.
Sintaxe:
try
{
//trecho de código que pode vir a lançar uma exceção
}
catch(tipo_exceçao_1 e)
{
//ação a ser tomada
}
catch(tipo_exceçao_2 e)
{
//ação a ser tomada
}
catch(tipo_exceçao _n e)
{
//ação a ser tomada
}
finally
{
//ação a ser tomada
}
Exemplo:
public class aumentaFrase {
public static void main(String args[])
{
String frase = null;
String novaFrase = null;
try
{
novaFrase = frase.toUpperCase();
}
catch(NullPointerException e)
{
System.out.println("O frase inicial está nula, para
solucional tal o problema, foi lhe atribuito um valor default.");
frase = "Frase vazia";
}
finally
{
novaFrase = frase.toUpperCase();
}
System.out.println("Frase antiga: "+frase);
System.out.println("Frase nova: "+novaFrase);
}
}
Quando este código fosse executado, o mesmo lançaria uma NullPointerException, porém esta exceção será tratada desta vez, sendo a mesma capturada pelo catch{} e dentro deste bloco as devidas providências são tomadas. Neste caso é atribuído um valor default à variável frase. Neste exemplo, mesmo o código lançando uma exceção durante a sua execução e a mesma sendo capturada pelo catch, uma determinada ação será tomada no bloco finally, neste caso tanto com a exceção ou não será executada a linha “ novaFrase = frase.toUpperCase();, tornando todas letras da frase maiúsculas. A saída deste programa seria a seguinte:
array4
Comandos throw e throws
Imagine uma situação em que não é desejado que uma exceção seja tratada na própria classe ou método, mas sim em outro que venha lhe chamar. Para solucionar tal situação utilizamos o comando throws na assinatura do método com a possível exceção que o mesmo poderá a vir lançar.
Sintaxe:
tipo_retorno nome_metodo() throws tipo_exceção_1, tipo_exceção_2, tipo_exceção_n
{
…
}
Onde:
- tipo_retorno – Tipo de retorno do método.
- nome_metodo() - Nome do método que será utilizado.
- tipo_exceção_1 a tipo_exceção_n – Tipo de exceções separadas por virgula que o seu método pode vir a lançar.
Exemplo:
public class TesteString {
private static void aumentarLetras() throws NullPointerException //lançando excessão
{
String frase = null;
String novaFrase = null;
novaFrase = frase.toUpperCase();
System.out.println("Frase antiga: "+frase);
System.out.println("Frase nova: "+novaFrase);
}
public static void main(String args[])
{
try
{
aumentarLetras();
}
catch(NullPointerException e)
{
System.out.println("Ocorreu um
NullPointerException ao executar o método aumentarLetras() "+e);
}
}
}
Neste exemplo será lançada uma exceção no método aumetarLetras():
private static void aumentarLetras() throws NullPointerException
E o mesmo será tratado no método main().
...
try
{
aumentarLetras();
}
catch(NullPointerException e)
{
System.out.println("Ocorreu um NullPointerException ao
executar o método aumentarLetras() "+e);
}
…
Saída:
Ocorreu um NullPointerException ao executar o método
aumentarLetras() java.lang.NullPointerException.
Agora imagine o caso em que seja necessário lançar uma exceção padrão ao invés de uma especifica. Para resolver este problema, utilizamos o comando throw dentro do bloco catch que desejamos converter a exceção.
Sintaxe:
try
{
//…
}
catch(tipoExcessão_1 e)
{
throw new novoTipoExceçao(e);
}
Onde:
- tipoExcessão_1 e – Tipo de exceção que pode ser capturada pelo bloco catch.
- NovoTipoExceçao – Tipo de exceção que será lançada.
Exemplo:
public class TesteString {
private static void aumentarLetras() throws Exception //lançando exceção
{
String frase = null;
String novaFrase = null;
try
{
novaFrase = frase.toUpperCase();
}
catch(NullPointerException e)
{
throw new Exception(e);
}
System.out.println("Frase antiga: "+frase);
System.out.println("Frase nova: "+novaFrase);
}
public static void main(String args[])
{
try
{
aumentarLetras();
}
catch(Exception e)
{
System.out.println("Ocorreu uma exceão ao
executar o método aumentarLetras() "+e);
}
}
}
Neste exemplo será lançada uma NullPointerException e a mesma será convertida para Exception e relançada como Exception no método aumentarLetras() e, por fim, a mesma é tratada no método main().
Saida:
Ocorreu uma exceão ao executar o método aumentarLetras()
java.lang.Exception: java.lang.NullPointerException
Criando exceções
Assim como qualquer objeto, em Java também é possível criar suas próprias exceções. Imagine um cenário em que nenhuma exceção existente faça sentido para ser lançada por você.
Por exemplo, imagine que por algum motivo você precisa que uma exceção seja lançada quando a letra B ou b não existe e determinada frase, como não existe nenhuma exceção específica para este caso será necessário criar uma exceção.
Criando uma exceção para ser lançada toda vez que uma letra B ou B não é encontrada em uma determinada frase.
public class SemLetraBException extends Exception {
@Override
public String getMessage(){
return "Não existe letra B em sua frase";
}
}
Toda exceção criada deve estender Exception, neste exemplo foi sobrescrito o método getMessage(), que é exibida no prompt toda vez que a exceção é lançada.
Utilizando a exceção
Abaixo segue um exemplo que é utilizada a exceção criada acima.
public class TesteExcecao {
public static void main(String args[]) throws SemLetraBException
{
String frase = "Sou um teste!";
if(!frase.contains("b") || !frase.contains("B"))
throw new SemLetraBException();
}
}
Quando o programa acima fosse executado, uma exceção do tipo SemLetraBException() seria lançada. Abaixo está a saída exibida no prompt:
Exception in thread "main" SemLetraBException: Não existe letra B ou b em
sua frase at TesteExcecao.main(TesteExcecao.java:8)
Conclusão
Como foi possível ver ao longo do artigo, o tratamento de exceções em Java é bem simples e sua manipulação pode ser feita de acordo com o que o programador deseja, desde tratá-la no próprio método ou lança-la para ser tratada em um método que venha chamar o método que lança a mesma.
Confira também
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Vídeo