Exceptions? Não entendo sua utilidade

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á!

Primeiramente, bem-vindo ao GUJ! Quando tiver um tempo, dê uma lida nesse post que explica como usar corretamente os recursos do fórum :wink: :
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:

  1. Se o arquivo for encontrado, seu conteúdo é exibido no println, e a mensagem de erro não será exibida.
  2. 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.
  3. 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.[/quote]

[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.

[quote=ECO2004]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.[/quote]
Estranho… fiz um teste aqui com seu código e compilou. Qual é o erro que dá para você?

[quote=Anime]Oi,

Não precisa dar bronca é só explicar… :? [/quote]
Não se preocupe, foi com jeitinho :smiley:
Para o bem dele…

[quote=gomesrod][quote=ECO2004]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.[/quote]
Estranho… fiz um teste aqui com seu código e compilou. Qual é o erro que dá para você?

[quote=Anime]Oi,

Não precisa dar bronca é só explicar… :? [/quote]
Não se preocupe, foi com jeitinho :smiley:
Para o bem dele…[/quote]

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,

[quote=ECO2004]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 ?[/quote]

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.

[code]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 ");
	 }
}[/code]

Quando você faz:

[code] 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 ");
	}
}[/code]

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!

[quote=lina]Oi,

[quote=ECO2004]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 ?[/quote]

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.

[code]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 ");
	 }
}[/code]

Quando você faz:

[code] 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 ");
	}
}[/code]

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![/quote]

[b]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 [quote]throws ArithmaticException, Exception[/quote]

e colocar um catch para cada caso?

[quote]catch (Exception ex1 ){}
catch (ArithmaticException ex2){}[/quote]

[/b]

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!

[quote=lina]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![/quote]

[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:

[code]
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!!!
	}
}[/code]

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:

[code]
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);
}[/code]

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.