Para que serve o tratamento de erros/exceptions? São a mesma coisa?
Tem os tais blocos try/catch, para que cada um serve? Alguém tem algum tutorial ou poderia me dar um exemplo? Agradeço desde já!
Exceptions? Não entendo sua utilidade
29 Respostas
Primeiramente, bem-vindo ao GUJ! Quando tiver um tempo, dê uma lida nesse post que explica como usar corretamente os recursos do fórum
:
http://www.guj.com.br/posts/list/50115.java
Exceptions servem para sinalizar condições anormais da execução de um programa. Errors, por outro lado, são condições irrecuperáveis, que não tem como seu programa se safar (por exemplo, falta de memória).
Por exemplo, vamos supor que você vá criar um método:
String leArquivo(File arquivo);
O que fazer quando o arquivo não existir?
Há duas possibilidades. A primeira, usada no C e C++, é retornar um código de erro. A segunda, é lançar uma FileNotFoundException.
O código de erro tem vários problemas. Primeiro de tudo, ele não interrompe o fluxo do método. Você teria que interrompe-lo por sua própria conta. O segundo, é que o código pode não ficar suficientemente claro. Finalmente, você é obrigado a retornar esse código de erro em algum lugar, e como funções geralmente só aceitam um único valor de retorno, ou o retorno normal (nesse caso o conteúdo do arquivo), ou o código de erro teriam de ser passados por referência.
O bloco try, catch, serve para verificarmos se uma exceção ocorreu e colocarmos algum tipo de tratamento. Por exemplo:
public void imprimirArquivo(File file) {
try {
String arq = leArquivo(file);
System.out.println(arq);
} catch (FileNotFoundException e) {
System.out.println("O arquivo não foi encontrado!");
}
}
Esse código informa ao usuário a mensagem “O arquivo não foi encontrado!”, caso o arquivo não esteja presente.
Note algumas coisas interessantes:
- Se o arquivo for encontrado, seu conteúdo é exibido no println, e a mensagem de erro não será exibida.
- Se o arquivo não for encontrado, o método leArquivo lancará a exceção. O código desvia imediatamente para o catch() e, portanto, o System.out.println(arq) não é exibido.
- Se removermos o try…catch, o println ainda não seria exibido. O java automaticamente jogaria a exceção para quem chamou a função imprimirArquivo. Isso é mais difícil de se fazer se tivéssemos retornado um código de erro.
No caso do Java, existe uma vantagem adicional em se usar exceções. Toda exceção contém a stack trace, ou seja, um texto contendo o local exato de onde o erro ocorreu.
O Java também suporta dois tipos de exceções, checked e unchecked. A diferença é que o programador é obrigado a ter um try…catch para a primeira ou passa-la adiante, enquanto no caso da segundo tipo é opcional.
Finalmente, em alguns casos, é necessário fazer uma finalização, ocorrendo ou não um erro. Para esses casos, você pode usar um finally, associado ao seu bloco try…catch.
Para mais informações veja o textos:
http://java.sun.com/docs/books/tutorial/essential/exceptions/
http://blog.caelum.com.br/2006/10/07/lidando-com-exceptions/
depois da explicacao do vinny nao tenho nem o q falar… parabens!! mais exceptios eh quando vc tem algo que eh perigoso… que pode lancar um erro indesejavel e vc nao quer mostrar esse erro para o usuario e quer trata-lo um exemplo:
7/0? isso eh possivel? nao… lancar um erro indesejavel para o cliente mais vc nao quer q ele veja na telinha dele aqueles codigos “esquisitos” entao vc trata(catch)… o uso de Exceções é quando algo é perigoso… ahhh como vou saber que algo eh perigoso… dar uma olhda na api… que vc vai ver o que eh perigoso ou nao…
os amigos estao corretos.
veja bem como o propio nome dizm isso e’ para testar excessoes
vc pode lancar um codigo ou tentar rodar o codigo
( try )
xxxx
xxxxx
Caso ocorro algo de errado vc pode tratar o erro, desta forma vc poderia ate evitar um travamento
quando eh realmente necessario tratar uma exception o copilador ira avisar caso vc nao faça. nao se preocupe… =)
Nem sempre, meu caro. Ele reconhece as exceptions que são definitivamente declaradas. Tente executar o seguinte:
public class TesteExc {
public static void main(String[] args) {
int a = 2;
int b = 0;
System.out.println(a/b);
}
}
Vai gerar uma exception mas o compilador não vai reclamar. Quer saber por que? Dê uma lida em: http://java.sun.com/docs/books/tutorial/essential/exceptions/
E procure também por unchecked exceptions.
Até!
obrigado pessoal agora ficou mais claro pra mim!
Olá pessoal!
Tenho uma dúvida com relação a excessões. Tem diferença entre usar um throws Exception na frente do método a usar try e catch ?
Deixe-me adivinhar: você está usando o Quick-Fix do Eclipse e até hoje acha que qualquer uma das opções dá na mesma? (ou seja, o vermelhinho some)
Muito cuidado! É importante aprender os fundamentos da linguagem antes de utilizar os recursos mais avançados da IDE. Há uns dias atrás eu tive que dar uma bronca em um desenvolvedor junior na empresa justamente por isso, deu um erro no Eclipse e eu peguei ele no flagra apertando Ctrl-1 e escolhendo uma das soluções aleatoriamente, sem pensar na causa. :shock:
E respondendo à pergunta, os dois fazem coisas bem diferentes: um deles você usa para tratar a exceção, o outro serve para dizer ao compilador que não vai tratar, deixando que o chamador cuide disso.
Oi,
Não precisa dar bronca é só explicar… :?
Deixe-me adivinhar: você está usando o Quick-Fix do Eclipse e até hoje acha que qualquer uma das opções dá na mesma? (ou seja, o vermelhinho some)
Muito cuidado! É importante aprender os fundamentos da linguagem antes de utilizar os recursos mais avançados da IDE. Há uns dias atrás eu tive que dar uma bronca em um desenvolvedor junior na empresa justamente por isso, deu um erro no Eclipse e eu peguei ele no flagra apertando Ctrl-1 e escolhendo uma das soluções aleatoriamente, sem pensar na causa. :shock:
E respondendo à pergunta, os dois fazem coisas bem diferentes: um deles você usa para tratar a excessão, o outro serve para dizer ao compilador que não vai tratar, deixando que o chamador cuide disso.
[b]Não, não estou usando o quick fix.
Tem como alguém, me fazendo o favor, explicar então a diferença? Queria saber a relação entre o tipo da excessão após o throw e o capturado pelo catch.
Obrigado.[/b]
Por exemplo, por que o meu código abaixo não compila?
public static int Funcao(int x, int y) throws Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
finally
{
System.out.println(" 6 ");
}
}
Faz de conta que chamo Funcao na main com parâmetros 1 e 0.
Por exemplo, por que o meu código abaixo não compila?public static int Funcao(int x, int y) throws Exception { try { System.out.println(" 4 "); return x/y; } catch(ArithmeticException ex) { System.out.println(" 5 "); throw ex; } finally { System.out.println(" 6 "); } }Faz de conta que chamo Funcao na main com parâmetros 1 e 0.
Estranho… fiz um teste aqui com seu código e compilou. Qual é o erro que dá para você?
Oi,Não precisa dar bronca é só explicar… :?
Não se preocupe, foi com jeitinho

Para o bem dele…
Por exemplo, por que o meu código abaixo não compila?public static int Funcao(int x, int y) throws Exception { try { System.out.println(" 4 "); return x/y; } catch(ArithmeticException ex) { System.out.println(" 5 "); throw ex; } finally { System.out.println(" 6 "); } }Faz de conta que chamo Funcao na main com parâmetros 1 e 0.
Estranho… fiz um teste aqui com seu código e compilou. Qual é o erro que dá para você?Oi,Não precisa dar bronca é só explicar… :?
Não se preocupe, foi com jeitinho
Para o bem dele…
A sugestão de concerto é colocar um throw na função “Funcao(1, 0)”, na main
Vou postar o código completo:
public class Main
{
public static int Funcao(int x, int y) throws ArithmeticException
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 2 ");
throw ex;
}
finally
{
System.out.println(" 3 ");
}
}
public static int Funcao_2(int x, int y) throws Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
finally
{
System.out.println(" 6 ");
}
}
public static void main(String[] args)
{
Funcao_2(1,0);
}
}
[b]Uma outra dúvida que tenho é:
- No primeiro método, eu coloco um throw ArithmaticException e depois trato ArithmaticException no catch.
- No segundo método (Funcao_2), eu coloco um throw Exception e trato um ArithmaticException no catch.
O erro dá na chamada da função Funcao_2, na main.
1 - Qual a relação entre a excessão depois do throw e a tratada no catch? - em Funcao, por serem a mesma, funcionou…
2 - Qual a diferença entre try e catch para apenas throw (alguma excessão) ? - em Funcao_2, por serem diferentes, não compila…
[/b]
Oi,
Olá pessoal!Tenho uma dúvida com relação a excessões. Tem diferença entre usar um throws Exception na frente do método a usar try e catch ?
Podemos definir 'throws' como lançar/atirar/jogar.
No caso acima, você irá lançar uma Exception. Ou seja, poderá ser lançada qualquer exceção e não uma em especifico!
No exemplo abaixo, você lança o ArithmeticException, que por sua vez já esta sendo tratado no código. Logo o compilador identifica isso.
public static int Funcao(int x, int y) throws ArithmeticException
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 2 ");
throw ex;
}
finally
{
System.out.println(" 3 ");
}
}
Quando você faz:
public static int Funcao_2(int x, int y) throws Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
finally
{
System.out.println(" 6 ");
}
}
Você estará dizendo que ira ser lançado qualquer tipo de Exception. Sendo que no código você apenas trata o ArithmeticException.
Deu pra entender ?
Tchauzin!
Oi,Olá pessoal!Tenho uma dúvida com relação a exceções. Tem diferença entre usar um throws Exception na frente do método a usar try e catch ?
Podemos definir 'throws' como lançar/atirar/jogar.
No caso acima, você irá lançar uma Exception. Ou seja, poderá ser lançada qualquer exceção e não uma em especifico!
No exemplo abaixo, você lança o ArithmeticException, que por sua vez já esta sendo tratado no código. Logo o compilador identifica isso.
public static int Funcao(int x, int y) throws ArithmeticException { try { System.out.println(" 1 "); return x/y; } catch(ArithmeticException ex) { System.out.println(" 2 "); throw ex; } finally { System.out.println(" 3 "); } }Quando você faz:
public static int Funcao_2(int x, int y) throws Exception { try { System.out.println(" 4 "); return x/y; } catch(ArithmeticException ex) { System.out.println(" 5 "); throw ex; } finally { System.out.println(" 6 "); } }Você estará dizendo que ira ser lançado qualquer tipo de Exception. Sendo que no código você apenas trata o ArithmeticException.
Deu pra entender ?
Tchauzin!
Entendi.
E se seu quisesse que ArithmaticException fosse tratado nesse catch e o restante em outro?
1 - 1/0 entraria na ArithmaticException.
2 - InputMismatchException, p. ex. , e demais em um segundo catch.
Eu teria que colocar na frente do método
throws ArithmaticException, Exception
e colocar um catch para cada caso?
catch (Exception ex1 ){} catch (ArithmaticException ex2){}
Oi,
O catch contendo apenas Exception deverá ser sempre o ultimo.
catch (ArithmaticException ex){}
catch (NumberFormatException ex ){}
catch (Exception ex ){}
Desta forma, todas as exceções que “escaparem” dos catchs específicos irão cair no cath “Deus” Exception.
Tchauzin!
Oi,O catch contendo apenas Exception deverá ser sempre o ultimo.
catch (ArithmaticException ex){} catch (NumberFormatException ex ){} catch (Exception ex ){}Desta forma, todas as exceções que “escaparem” dos catchs específicos irão cair no cath “Deus” Exception.
Tchauzin!
[b]Oi Lina!
Se eu fizer…[/b]
public static int Funcao_2(int x, int y) throws ArithmeticException, Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
catch( Exception ex)
{
System.out.println("causou");
throw ex;
}
finally
{
System.out.println(" 6 ");
}
}
[b]…o erro persiste. Sem o Exception após o thows, o erro também persiste.
1- Com o throws Exception, o erro que é dado é na chamada da função Funcao_2, na main, dizendo que “Exception” não foi tratada.
2- Sem o throws Exception, o erro que é dado é em “throw ex”, em “catch(Exception ex)”, dizendo que Exception não foi tratado.
[/b]
Oi,
È quase impossível explicar o inexplicável. Você está sem complicando d+ e não está entendendo a lógica.
No código:
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
catch( Exception ex)
{
System.out.println("causou");
throw ex;
}
Você está levantando a exceção ArithmeticException para a mesma ser tratado no catch Exception.
Porém, dentro do catch Exception você está levantando a mesma novamente. Logo, quem irá trata-la ???
Ao menos que você faça:
public static int Funcao_2(int x, int y) throws ArithmeticException, Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
catch( Exception ex)
{
System.out.println("causou");
throw ex;
}
finally
{
System.out.println(" 6 ");
}
}
public static void main(String[] args)
{
try
{
Funcao_2(2, 3);
}
catch (Exception e)
{
// TRATANDO O EXCEPTION AQUI!!!
}
}
Agora, você poderá tratar o Exception dentro do código e não no main, então irá notar que seu return x/y está no local errado:
public static int Funcao_2(int x, int y) throws ArithmeticException
{
try
{
System.out.println(" 4 ");
//return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
catch( Exception ex)
{
System.out.println("TRATEI O EXCEPTION AQUI!");
}
finally
{
System.out.println(" 6 ");
}
return x/y; // o retorno vem aqui!
}
/**
* @param args
*/
public static void main(String[] args)
{
Funcao_2(2, 3);
}
Tchauzin!
Eu não entendi direito.
ArithmeticException será tratado no catch (ArithmaticException) e no catch (Exception) ?
Isso foi o que entendi da sua explicação.
Você está levantando a exceção ArithmeticException para a mesma ser tratado no catch Exception.
Porém, dentro do catch Exception você está levantando a mesma novamente. Logo, quem irá trata-la ???
Eu não entendi direito.
ArithmeticException será tratado no catch (ArithmaticException) e no catch (Exception) ?
Isso foi o que entendi da sua explicação.
Oi,
Você está lançando novamente a exceção ArithmaticException dentro do catch (ArithmeticException ex).
A partir do momento que você faz throw ex, esta indicando que um outro catch deverá trata-la.
Tchauzin!
Bem estou acompanahndo e achei interessante, permitam-me interferir.
Então se entendi bem, no primeiro caso, esta lançando uma exceção ‘ArithmeticException’ é porque eu sei o tipo de exceção que o código do try pode gerar e trato ele no catch com ArithmeticException. É isso?
No seguno caso lanço uma exceção qualquer porque, supondo que eu não sei qual tipo de exceção o código pode gerar, ms sei que ele é ‘perigoso’. E consulto sobre isso olhando na API.
Então eu poderia trocar no segundo exemplo:
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
por:
catch(Exception ex)
{
System.out.println(" 5 ");
throw ex;
}
Que lança a exceção normal, ou tem alguma diferença nisso?
Outra pergunta, se estou executando a minha função no main, eu tenho que lançar uma exceção no metodo main?
Bem estou acompanahndo e achei interessante, permitam-me interferir.Então se entendi bem, no primeiro caso, esta lançando uma exceção ‘ArithmeticException’ é porque eu sei o tipo de exceção que o código do try pode gerar e trato ele no catch com ArithmeticException. É isso?
No seguno caso lanço uma exceção qualquer porque, supondo que eu não sei qual tipo de exceção o código pode gerar, ms sei que ele é ‘perigoso’. E consulto sobre isso olhando na API.
Então eu poderia trocar no segundo exemplo:
catch(ArithmeticException ex) { System.out.println(" 5 "); throw ex; }por:
catch(Exception ex) { System.out.println(" 5 "); throw ex; }
Que lança a exceção normal, ou tem alguma diferença nisso?Outra pergunta, se estou executando a minha função no main, eu tenho que lançar uma exceção no metodo main?
Sim, você poderia trocar.
Eu fiz uma diferenciação porque eu desejo tratar cada uma de uma maneira. Mas se quiser tratar todas as possíveis em uma Exception, pode.
Você está levantando a exceção ArithmeticException para a mesma ser tratado no catch Exception.
Porém, dentro do catch Exception você está levantando a mesma novamente. Logo, quem irá trata-la ???
Eu não entendi direito.
ArithmeticException será tratado no catch (ArithmaticException) e no catch (Exception) ?
Isso foi o que entendi da sua explicação.Oi,
Você está lançando novamente a exceção ArithmaticException dentro do catch (ArithmeticException ex).
A partir do momento que você faz throw ex, esta indicando que um outro catch deverá trata-la.
Tchauzin!
Obrigado pela ajuda!
[/b]
O meu maior problema está com o Exception…
Na main, eu tenho, p. ex:
Funcao(10, 0);
Na implementação de Funcao, eu implemento um throws ArithmeticException e trato essa mesma excessão no catch.
Se eu coloco Exception apenas, no lugar de ArithmeticException e mudo no catch de ArithmeticException para Exception, diz na main que não tratei a excessão.
Antes:
public static Funcao f(int x, int y) throws ArithmeticException
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 2 ");
throw ex;
}
finally
{
System.out.println(" 3 ");
}
}
Depois:
public static int f(int x, int y) throws Exception
{
try
{
System.out.println(" 1 ");
return x/y;
}
catch(Exception ex)
{
System.out.println(" 2 ");
throw ex;
}
finally
{
System.out.println(" 3 ");
}
}
Por que com excessões em particular (Arithmetic, InputMismatch, IndexOutOfBounds…) funciona e com Exceptiom, que é generalizado, não funciona ?
lina:Podemos definir ‘throws’ como lançar/atirar/jogar.
No caso acima, você irá lançar uma Exception. Ou seja, poderá ser lançada qualquer exceção e não uma em especifico!
No exemplo abaixo, você lança o ArithmeticException, que por sua vez já esta sendo tratado no código. Logo o compilador identifica isso.
Mas quando você coloca “throws” no método:
public Integer dividir (int num1, int num2) throws ArithmeticException {
int res;
try {
res=num1/num2;
} catch (ArithmeticException ex) {
System.out.println(ex);
}
return res;
}
E depois chama este método (em outro método) você tem que colocar o “throws” de novo, sendo que este segundo não gera exceção:
public void resultado() throws ArithmeticException {
int n1=5;
int n2=0;
dividir(n1, n2);
}
Então eu pergunto é necessário dizer para os métodos (dividir e resultado) que poderá ser lançada uma exeção :?:
Apenas o “try catch” do método dividir seria necessário, não é :?:
lina:Podemos definir 'throws' como lançar/atirar/jogar.
No caso acima, você irá lançar uma Exception. Ou seja, poderá ser lançada qualquer exceção e não uma em especifico!
No exemplo abaixo, você lança o ArithmeticException, que por sua vez já esta sendo tratado no código. Logo o compilador identifica isso.
Mas quando você coloca "throws" no método:
public Integer dividir (int num1, int num2) throws ArithmeticException { int res; try { res=num1/num2; } catch (ArithmeticException ex) { System.out.println(ex); } return res; }E depois chama este método (em outro método) você tem que colocar o "throws" de novo, sendo que este segundo não gera exceção:
public void resultado() throws ArithmeticException { int n1=5; int n2=0; dividir(n1, n2); }Então eu pergunto é necessário dizer para os métodos (dividir e resultado) que poderá ser lançada uma exeção :?:
Apenas o "try catch" do método dividir seria necessário, não é :?:
No seu método resultado não precisa do throws, pois a exceção já foi tratada no seu método dividir.
Na segunda pergunta: sim, apenas o try e catch são suficientes.
Pelo que andei vendo, e muito, o throws é um indicador que poderão ser lançados as exceções que você colocar.
O único problema é que não pode colocar throws Exception no módulo em que está tratando a exceção. Se a chamada da função estiver em um try, catch, aí você poderá colocar quantos catches quiser. Até mesmo um Exception. Na implementação de seu módulo, aí sim é permitido fazer um throws Exception, junto com outros, caso queria.
Espero que alguém saiba explicar o porquê de não poder colocar um throws Exception no módulo em que está sendo tratado as exceções - Em "não compila, abaixo"
Abaixo um exemplo:
Pode:
public static void main(String[] args)
{
g(10,0);
}
public static int g(int x, int y)
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
catch(Exception e)
{
System.out.println("Erro inexplicado!");
return -1;
}
}
Não compila:
public static int g(int x, int y) throws Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
catch(Exception e)
{
System.out.println("Erro inexplicado!");
return -1;
}
}
Também não compila:
public static int g(int x, int y) throws ArithmeticException, Exception
{
try
{
System.out.println(" 4 ");
return x/y;
}
catch(ArithmeticException ex)
{
System.out.println(" 5 ");
throw ex;
}
catch(Exception e)
{
System.out.println("Erro inexplicado!");
return -1;
}
}
Só uma observação que gostaria de colocar. [além de ajuda tb quero ajudar]
Os dois tipos de exceções são verificadas e não-verificadas. Um exemplo da primeira é um IOException. Esse tipo de exceção - verificado - impõe o requisito catch or declare, que nada mais é que é obrigatório ter nessas nos código que possam gerar essas exceções ou um throws ou um try e catch. Sem um dos dois, o compilador gera errro. Tente, por ex., criar um objeto Writer sem um dos dois e verá.
A segunda classe de exceções - não verificadas - não impõe nem try/catch nem throws.
Oi,Não precisa dar bronca é só explicar… :?
Não se preocupe, foi com jeitinho
Para o bem dele…
Que bom… 
Pior que fiquei preocupada mesmo rs…
Sim eu entendir isto, pela lógica a exceção já foi tratada.
Sim eu também entendir isto
, mas o caso é que se você pensar: "…vou colocar os dois (try/catch e throws) porque o Netbeans sugere: “…circundar com throws”, na primeira opção e/ou “…circundar com try/catch”, na segunda opção. Aqui que acontece o problema, você coloca os dois, mesmo
apenas o try e catch são suficientes., ai cada método que você chamar (incluse no construtor) o Netbeans pede para “…circundar com throws”, cada método.
Enfim, isto não é uma dúvida, é uma afirmação, que pode confundir :? um pouco no começo.