try-catch-e-o-throws
Você vai aprender
O que é uma exceção
Diferentes modos de tratar uma exceção
Pré-Requisitos
Noções básicas de Java
Exceções em código
Exceções é um evento que acontece durante a execução de um programa, que acaba interrompendo o fluxo normal de um código. Uma exceção pode ocorrer por vários motivos.
Por exemplo, você pode estar tentando acessar o índice de uma String e acontecer isso.
public class Main
{
public static void main(String[] args) {
String s = "Hello world";
char c = s.charAt(20); // Impossível, pois "s" tem tamanho 11
System.out.println(c);
}
}O código vai mandar esse erro para o terminal e terminar a execução do programa, sem chegar no println. Nesse caso o nosso problema é que não colocamos a chamada da função charAt em volta de um try catch.
Um bloco try catch é onde podemos colocar código que potencialmente pode gerar um ou mais erros.
Observe o exemplo abaixo:
Desta vez, nós declaramos um valor inicial para a variável c, e colocamos a lógica que chama a função dentro do bloco try, neste bloco as funções potencialmente perigosas são colocadas, e caso aconteça algum erro, o código vai cair no bloco catch onde podemos tratar casos onde aconteça um erro.
Perceba que o catch funciona como uma função, e recebe um parâmetro, neste caso ele recebe a nossa exceção, que pode ser imprimida com mais detalhes chamando a função printStackTrace().
Se rodarmos esse código, percebe que, por mais que o erro aconteça, a execução chega até o final.
Uma coisa importante a notar, é que nem toda função que joga uma exceção irá exigir que você trate da mesma. Você pode utilizar a função charAt e nunca precisar colocar um bloco try catch para tratar possíveis erros.
Mas existe casos onde o tratamento de erro é obrigatório, então vamos olhar esse caso, já abordando também a outra problemática: "Como podemos tratar múltiplas exceções?"
Multiplas exceções
Considere o seguinte programa.
Talvez nem tudo que você acabou de ler, mas o código chama a função lerNumerosDeArquivo para extrair das linhas de um arquivo.txt números válidos, que serão colocados dentro de um arranjo de inteiros. Por fim, a função main irá imprimir cada número um por um.
Se você tentar executar o código acima, você terá varios erros:
Todos essas exceções o Java pede que você trate elas obrigatoriamente em código. Além disso, tem também o NumberFormatException que também pode acontecer no código acima se alguma linha for encontrada que contém um número inválido, porém o Java não obriga o programador a tratar esse problema.
Um jeito de lidar esse problema, seria rodear toda a lógica do programa que pode dar algum erro de exceção, com um try catch e adicionar um bloco catch para cada exceção:
Com isso, o nosso código agora está funcional e trata todos os possíveis erros, porém, agora a nossa função está muito bagunçada. Se quisermos podemos em vez de usar três blocos catch podemos colocar só um, e colocando como argumento o objeto Exception, que conseguirá encapsular todas as exceções ja que o mesmo é a classe pai de todas as exceções.
Agora sim, a nossa lógica foi simplificada, porém, em troca, perdemos a flexibilidade de poder manejar cada exceção individualmente. Uma outra alternativa, seria fazer com que a função não trate a exceção, mas sim apenas retornar para função que chamou ela, as exceções para serem tratadas.
Observe o exemplo abaixo
Usando a palavra throws após a declaração da função, é possível jogar qualquer erro lançado pela função para outra. Desta forma, agora toda a lógica de tratamento de exceção foi colocada na função main que está chamado a função lerNumerosArquivos, aqui nós temos duas opções em como tratar esse problema na main, o primeiro seria fazer a função também usar o throws, porém desta forma não estaremos realmente tratando a exceção. A melhor forma aqui seria utilizar um try catch.
Pronto agora o nosso programa conseguiu tratar as exceções, e também caso dê algum erro, o nosso programa termina a execução, usando o System.exit(-1);.
Para finalizar vamos simplificar mais uma vez o código e permitir uma maior flexibidade no nosso programa. Supondo que eu não queira parar a execução do programa caso eu leia um número impossível, em vez da própria main tratar esse problema, podemos jogar a responsabilidade disso para a nossa função lerNumeroArquivos uma vez que fazendo isso, irá nos permitir ainda executar o código e imprimir todos os números válidos no arquivo.
Pronto, acho que por agora está o suficiente ;-) . Agora tente rodar esse código, colocando os números abaixo em um "arquivo.txt"
O seu resultado tem que ser algo parecido com isso:
Links úteis
Last updated