Finally e Throw

E ae pessoal, blz?
eu tenho duas dúvidas!

  1. qual a função do bloco finally? vi em livros e apostilas que serve pra ser executado sempre, havendo exception ou não! mas… ao invés de fazer um bloco finally não mais fácil jogar o código q iria ficar dentro do bloco finally pra depois do bloco catch???
    Os trechos de código abaixo têm alguma diferença?
    try{
    numerador = input.nextInt();
    denominador = input.nextInt();
    System.out.printf("%d",numerador/denominador);
    }catch(ArithmeticException e){
    System.out.printf(“Divisão por zero!”);
    }finally{
    System.out.printf(“Fim do programa!”);
    }

try{
numerador = input.nextInt();
denominador = input.nextInt();
System.out.printf("%d",numerador/denominador);
}catch(ArithmeticException e){
System.out.printf(“Divisão por zero!”);
}
System.out.printf(“Fim do programa!”);

  1. Outra dúvida é sobre Throw e Throws, não é q eu confunda essas duas palavras mas não sei pra q servem!
    O trecho de código abaixo não funcionaria com Throw e sem Throw do mesmo geito???

public void int divide(int numerador, int denominador) Throw ArithmeticException{
return numerador/denominador;
}

try{
numerador = input.nextInt();
denominador = input.nextInt();
resultado = divide(numerador,denominador);
System.out.printf("%d",resultado);
}catch(ArithmeticException e){
System.out.printf(“Divisão por zero!”);
}

porfavor pessoal me tirem essas duvidas!
vlw!!!

Considere este bloco:

try { objeto = new Balangandã(); objeto.algumaCoisa(); }catch(AlgumaException e){ throw new OutraException(e); } finally{ objeto.close(); }

Quando chegar no catch, vc quer ‘relançar’ esta exception. a unica forma de executar o método close seria no bloco finally.

Ok, mas ai vc vai dizer, puxa, coloca o objeto.close() acima do throw new… ai vc vai escrever 2 vezes objeto.close() ?

[quote=henriqueers]2) Outra dúvida é sobre Throw e Throws, não é q eu confunda essas duas palavras mas não sei pra q servem!
O trecho de código abaixo não funcionaria com Throw e sem Throw do mesmo jeito???[/quote]

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ArithmeticException.html

Resposta:
public class ArithmeticException extends RuntimeException

Uma coisa que sinto falta no C++ é que ele não tem finally.
Isso acaba forçando você a criar um try dentro do outro, ou pior, criar umas classes esquisitas só para suprir a falta do finally, ou usar uma extensão do seu compilador que implementa o "finally" e deixa seu código não portável.

Tabelinha de correspondências:
Java -> C++
try -> try
catch -> catch
catch (Throwable) -> catch (…)
finally -> não tem; no MSVC++ você usa __finally, mas tem de usá-lo com __try e __catch
throw -> throw
throws -> throw (não implementado direito no MSVC++ e em vários compiladores)

[quote=henriqueers]E ae pessoal, blz?
eu tenho duas dúvidas!

  1. qual a função do bloco finally? vi em livros e apostilas que serve pra ser executado sempre, havendo exception ou não! mas… ao invés de fazer um bloco finally não mais fácil jogar o código q iria ficar dentro do bloco finally pra depois do bloco catch???
    Os trechos de código abaixo têm alguma diferença?
    try{
    numerador = input.nextInt();
    denominador = input.nextInt();
    System.out.printf("%d",numerador/denominador);
    }catch(ArithmeticException e){
    System.out.printf(“Divisão por zero!”);
    }finally{
    System.out.printf(“Fim do programa!”);
    }

try{
numerador = input.nextInt();
denominador = input.nextInt();
System.out.printf("%d",numerador/denominador);
}catch(ArithmeticException e){
System.out.printf(“Divisão por zero!”);
}
System.out.printf(“Fim do programa!”);

[/quote]

O bloco Finally vai ser sempre executado, não importa qual execeção ocorra (ou mesmo caso não ocorra uma).
O finally é muito usado para “limpar” a bagunça que o try começou e não pode terminar por causa da exceção.

throws é usado para declarar que um método lança uma ou mais exceções.
throw é usado para lançar aquela exceção.

public void testaIdade (int idade ) throws IdadeInsuficienteException { if (idade >= 18) { podeVerSitePorno(); } else { throw new IdadeInsuficienteException("Vai pra casa estudar moleque"); } }

Vlw galera, entendi a função do finally e do Throw :smiley:
só estou com dúvida agora em Throws… :?
Throws só serve pra falar q o método pode lançar uma exceção? então se o método não tiver Throws ele não pode lançar uma exceção??? quando lanço exceptions no main eu nunca uso Throws… :?

Outra coisa interessante. O finally é executado mesmo que haja returns dentro do bloco try.
Teste aí:

void finallyTest() { try { System.out.println("Rodando try..."); return; } catch (Exception e) { System.out.println("Catch"); } finally { System.out.println("Finally!") } }

A saída será:
Rodando try…
Finally!

Isso pode ser muito útil, pois permite que você coloque code guards dentro do bloco try. Como no exemplo abaixo:

public void alterarDadosDoCliente(int codCliente) { ResultSet rs = null; try { rs = statement.createResultSet("SELECT * FROM Clientes where codCliente = " + codCliente); if (!rs.next) //Sem cliente? return; //Retornamos direto! //Faz o que tem que fazer aqui } finally { if (rs != null) rs.close(); //Fecha de qualquer jeito } }

E Thingol, concordo com você. O finally faz uma falta imensa no C++.

[quote=henriqueers]Vlw galera, entendi a função do finally e do Throw :smiley:
só estou com dúvida agora em Throws… :?
Throws só serve pra falar q o método pode lançar uma exceção? então se o método não tiver Throws ele não pode lançar uma exceção??? quando lanço exceptions no main eu nunca uso Throws… :?[/quote]

vale o mesmo raciocinio das checked e unchecked exceptions.

se vc vai lancar uma exception que é uma runtime exception (ou filha dela), não precisa do throws.

entretanto se vc vai lançar uma checked exception (como IOException), vc precisa sinalizar.

uma das utilidades é: vc tem um objeto e vai chamar o metodo x. o método x PODE lançar uma checked exception, e vc TEM que tratar. se vc olhar pra assinatura do método vai ver o throws, então vc ja se liga nisso antes de ver um erro em tempo de compilação “pombas meu filho… coloca um try/catch ali…”.

vlw ae pessoal, ajudarão pra caramba!!! :smiley:
flw!!! 8)

No bloco finally podemos colocar instruções para o fechamento da conexão com o banco de dados, ocorrendo ou não uma exception o bloco finally será executado, e a conexão com o banco encerrada.

Se uma exception for lançada a partir do bloco finally, nenhum dos blocos catch será alcançado.

O mesmo acontece se vc colocar um return (alias C# não deixa vc fazer isso). Use o finally com parcimônia :slight_smile:

[quote=peczenyj]Se uma exception for lançada a partir do bloco finally, nenhum dos blocos catch será alcançado.

O mesmo acontece se vc colocar um return (alias C# não deixa vc fazer isso). Use o finally com parcimônia :)[/quote]

Não entendi…!?

No C# tentei isto:

try { Console.WriteLine("TRY"); throw new Exception(); } catch { Console.WriteLine("CATCH"); return; } finally { Console.WriteLine("FINALLY"); throw new Exception(); }

E passou em todos, a saida fio TRY CATCH FINALLY.

Tentei colocar um return dentro do Finally mas não deixa compilar :stuck_out_tongue:

Não entendi qual a grande diferença no Try/Catch/Finally entre Java e C#, ao meu ver fazem o mesmo… usei o .Net 2.

Fiz o teste no Java também, e no Java deixa fazer um return dentro do Finally.

Com o throw new Exception(); dentro do Finally tanto no Java e no C#, em ambos passou pelo Catch.

Portanto acho que esta afirmação esta incorreta:

[quote=peczenyj]Se uma exception for lançada a partir do bloco finally, nenhum dos blocos catch será alcançado.

O mesmo acontece se vc colocar um return (alias C# não deixa vc fazer isso). Use o finally com parcimônia :)[/quote]

Desculpe, acho que não expliquei direito:

public class A{ public static void main (String [] a){ try{ doIt(); }catch(Exception e){ e.printStackTrace(); } } public static void doIt() throws Exception{ try { System.out.println("try"); throw new Exception("saindo do try"); }catch(Exception e){ System.out.println("catch"); throw new Exception("saindo do catch"); }finally{ System.out.println("finally"); // throw new Exception("saindo do finally"); // return; } } }

Digamos que vc vai “relançar” uma exception pelo bloco catch. O resultado desse programa é

try catch finally java.lang.Exception: saindo do catch at A.doIt(A.java:15) at A.main(A.java:4)

ok, mas descomente agora o return.

try catch finally

comente o return e descomente o throw new …

try catch finally java.lang.Exception: saindo do finally at A.doIt(A.java:18) at A.main(A.java:4)

Na verdade eu me baseei em um exemplo que só tinha throw new e achei que era sempre assim. pelo visto o bloco catch não é 100% ignorado, mas se vc quiser relançar uma exception, por exemplo, o resultado pode não ser o esperado. enfim, nada que uma boa hora de testes não resolva :slight_smile:

Qual a utilidade de um try sem catch?

[code]try {
// qualquer coisa
}
finally {

}[/code]

Garantir que algum código será executado, mesmo em caso de exceção ou de um return.
Ao mesmo tempo, você ainda deixa a exceção pular para a classe de cima, para que ele saiba sobre o erro.

o finally pode liberar algum recurso ou fechar alguma stream e, sem o catch nesse bloco, talvez vc queira tratar a exception do bloco try externamente, no método que chama esse método, por exemplo.

[quote=peczenyj]Desculpe, acho que não expliquei direito:

public class A{ public static void main (String [] a){ try{ doIt(); }catch(Exception e){ e.printStackTrace(); } } public static void doIt() throws Exception{ try { System.out.println("try"); throw new Exception("saindo do try"); }catch(Exception e){ System.out.println("catch"); throw new Exception("saindo do catch"); }finally{ System.out.println("finally"); // throw new Exception("saindo do finally"); // return; } } }

Digamos que vc vai “relançar” uma exception pelo bloco catch. O resultado desse programa é

try catch finally java.lang.Exception: saindo do catch at A.doIt(A.java:15) at A.main(A.java:4)

ok, mas descomente agora o return.

try catch finally

comente o return e descomente o throw new …

try catch finally java.lang.Exception: saindo do finally at A.doIt(A.java:18) at A.main(A.java:4)

Na verdade eu me baseei em um exemplo que só tinha throw new e achei que era sempre assim. pelo visto o bloco catch não é 100% ignorado, mas se vc quiser relançar uma exception, por exemplo, o resultado pode não ser o esperado. enfim, nada que uma boa hora de testes não resolva :slight_smile:
[/quote]

WOW agora sakei!!! :shock:

Caramba tem q se ter cuidado com isto, nunca return no finally :stuck_out_tongue:

Valew mais um truque :wink: