Considerando esse código, posso ter certeza absoluta de que o finally
bloco sempre é executado, não importa o que something()
seja?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
java
error-handling
return
try-catch-finally
Jonny Five
fonte
fonte
probably
.finally
; finalizador == ofinalize()
métodoRespostas:
Sim,
finally
será chamado após a execução dos blocos de códigotry
oucatch
.Os únicos horários
finally
que não serão chamados são:System.exit()
Runtime.getRuntime().halt(exitStatus)
try
oucatch
kill -9 <pid>
no UNIXfinally
bloco for executado por um encadeamento daemon e todos os outros encadeamentos não daemonfinally
forem encerrados antes, será chamadofonte
thread.stop()
, não necessariamente impede que ofinally
bloco seja executado.finally
bloco será chamado após otry
bloco e antes que o controle passe para as seguintes instruções. Isso é consistente com o bloco try que envolve um loop infinito e, portanto, o bloco final nunca é realmente chamado.Código de exemplo:
Resultado:
fonte
finally
cláusula-porreturn 2;
(Erro do compilador).Além disso, embora seja uma prática ruim, se houver uma declaração de retorno dentro do bloco final, ela superará qualquer outro retorno do bloco regular. Ou seja, o seguinte bloco retornaria false:
A mesma coisa com exceções lançadas no bloco final.
fonte
Aqui estão as palavras oficiais da Java Language Specification.
14.20.2 Execução de tentar finalmente e tentar pegar finalmente
A especificação para
return
realmente torna isso explícito:JLS 14.17 A declaração de retorno
fonte
Além das outras respostas, é importante ressaltar que 'finalmente' tem o direito de substituir qualquer exceção / valor retornado pelo bloco try..catch. Por exemplo, o código a seguir retorna 12:
Da mesma forma, o método a seguir não gera uma exceção:
Enquanto o método a seguir o lança:
fonte
OutOfMemoryError
? ;)return retVal
depois ofinally
bloco, apesar de que, naturalmente, pressupõe que você suprimiu algumas outras exceções porque o código não faria sentido contrário.Eu tentei o exemplo acima com pequenas modificações
O código acima gera:
Isso ocorre porque quando
return i;
executadoi
é um valor 2. Depois disso, ofinally
bloco é executado onde 12 é atribuídoi
e, em seguidaSystem.out
, é executado fora.Depois de executar o
finally
bloco, otry
bloco retorna 2, em vez de retornar 12, porque essa instrução de retorno não é executada novamente.Se você depurar esse código no Eclipse, sentirá que, após a execução
System.out
dofinally
bloco, areturn
instruçãotry
block será executada novamente. Mas esse não é o caso. Ele simplesmente retorna o valor 2.fonte
i
não fosse um objeto primitivo, mas um inteiro.Aqui está uma elaboração da resposta de Kevin . É importante saber que a expressão a ser retornada é avaliada antes
finally
, mesmo se for retornada depois.Resultado:
fonte
finally
. O cálculo do valor de retorno (printX()
aqui) ainda vem antes dele.System.out.println("finally trumps return... sort of");
porSystem.out.print("finally trumps return in try"); return 42;
Essa é toda a idéia de um bloco finalmente. Ele permite que você faça limpezas que, de outra forma, poderiam ser ignoradas porque você retorna, entre outras coisas, é claro.
Finalmente, é chamado independentemente do que acontece no bloco try (a menos que você chame
System.exit(int)
ou a Java Virtual Machine comece por algum outro motivo).fonte
Uma maneira lógica de pensar sobre isso é:
fonte
finalmente é sempre executado, a menos que haja um encerramento anormal do programa (como chamar System.exit (0) ..). então, seu sysout será impresso
fonte
Também um retorno finalmente jogará fora qualquer exceção. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
fonte
O bloco final é sempre executado, a menos que haja um encerramento anormal do programa, resultante de uma falha na JVM ou de uma chamada para
System.exit(0)
.Além disso, qualquer valor retornado do bloco final substituirá o valor retornado antes da execução do bloco final, portanto, verifique todos os pontos de saída ao usar try finalmente.
fonte
Não, nem sempre um caso de exceção é // System.exit (0); antes do bloco finally impede que finalmente seja executado.
fonte
Finalmente, sempre é executado. Esse é o ponto, apenas porque ele aparece no código após o retorno não significa que é assim que é implementado. O Java Runtime tem a responsabilidade de executar esse código ao sair do
try
bloco.Por exemplo, se você tiver o seguinte:
O tempo de execução irá gerar algo como isto:
Se uma exceção não capturada for lançada, o
finally
bloco será executado e a exceção continuará se propagando.fonte
Isso ocorre porque você atribuiu o valor de i como 12, mas não retornou o valor de i à função. O código correto é o seguinte:
fonte
Porque um bloco final sempre será chamado, a menos que você ligue
System.exit()
(ou o encadeamento trava).fonte
Concisa, na documentação oficial do Java (clique aqui ), está escrito que -
fonte
ENTRADA:
RESULTADO:
fonte
Sim, será chamado. Esse é o objetivo de ter finalmente uma palavra-chave. Se pular do bloco try / catch pudesse pular o bloco final, seria o mesmo que colocar o System.out.println fora do try / catch.
fonte
Sim, finalmente o bloco é sempre executado. A maioria dos desenvolvedores usa esse bloco para fechar a conexão com o banco de dados, o objeto de conjunto de resultados, o objeto de instrução e também usa no hibernate java para reverter a transação.
fonte
NEM SEMPRE
A especificação Java Idioma descreve como
try
-catch
-finally
etry
-catch
blocos de trabalhar em 14.20.2Em nenhum lugar ele especifica que o
finally
bloco é sempre executado. Mas, para todos os casos em que otry
-catch
-finally
etry
-finally
blocos de concluí-lo não especifica que antes da conclusãofinally
deve ser executado.O JLS não garante que o FIN seja executado após o CODE . O JLS garante que, se CODE e NEXT forem executados, FIN será sempre executado após CODE e antes de NEXT .
Por que o JLS não garante que o
finally
bloco seja sempre executado após otry
bloco? Porque é impossível. É improvável, mas possível, que a JVM seja abortada (interrupção, falha, desligamento) logo após concluir otry
bloco, mas antes da execução dofinally
bloco. Não há nada que o JLS possa fazer para evitar isso.Assim, qualquer software que, para o seu bom comportamento, dependa de
finally
blocos sempre executados após atry
conclusão dos mesmos, são corrigidos.return
instruções notry
bloco são irrelevantes para esse problema. Se a execução atingir o código após otry
-catch
-finally
, é garantido que ofinally
bloco tenha sido executado antes, com ou semreturn
instruções dentro dotry
bloco.fonte
Sim vai. Não importa o que aconteça em seu bloco try ou catch, a menos que System.exit () chamado ou a JVM tenha travado. se houver alguma declaração de retorno no (s) bloco (s), finalmente será executada antes dessa declaração de retorno.
fonte
Sim vai. O único caso em que a JVM sairá ou trava
fonte
Adicionar a resposta do @ vibhash como nenhuma outra resposta explica o que acontece no caso de um objeto mutável como o abaixo.
Saída
fonte
Eu tentei isso, é único thread.
O estado
main
Thread
estará emwait
estado para sempre, portantofinally
nunca será chamado ,portanto, a saída do console não
print
String
: depoiswait()
oufinally
Concordado com @Stephen C, o exemplo acima é um dos terceiro casos mencionados aqui :
Adicionando mais algumas possibilidades de loop infinito no seguinte código:
Caso 2: se a JVM travar primeiro
Ref: Como você trava uma JVM?
Caso 6: Se o
finally
bloco será executado pelo daemonThread
e todas as outrasThreads
saídas não-daemon anterioresfinally
forem chamadas.saída: Isso não imprime "Finalmente", o que implica que "Finalmente o bloco" no "daemon thread" não foi executado
fonte
Considere o seguinte programa:
A partir do Java 1.8.162, o bloco de código acima fornece a seguinte saída:
isso significa que usar
finally
para liberar objetos é uma boa prática, como o código a seguir:fonte
sb.setLength(0)
finalmente?sb = null;
adiciona apenas um código desnecessário. Entendo que você quer dizer que umfinally
bloco é um bom lugar para liberar recursos como uma conexão com o banco de dados ou algo assim, mas lembre-se de que seu exemplo pode confundir os recém-chegados.System.out.println("---AGAIN2---");
System.out.println(sb);
e é mais claro agora. Como foi, a saída foi contrária à sua tese: p Adicionei também a sua resposta, mas a edição deve ser aceita por um moderador ou alguém assim.Isso é verdade em qualquer idioma ... finalmente, sempre será executado antes de uma declaração de retorno, não importa onde esse retorno esteja no corpo do método. Se não fosse esse o caso, o bloco finalmente não teria muito significado.
fonte
Além do ponto sobre retorno na substituição final de um retorno no bloco try, o mesmo se aplica a uma exceção. Um bloco finalmente que lança uma exceção substitui um retorno ou exceção lançada de dentro do bloco try.
fonte
finally
será executado e isso é certo.finally
não será executado nos casos abaixo:caso 1 :
Quando você está executando
System.exit()
.caso 2:
Quando sua JVM / Thread falha.
caso 3:
Quando sua execução é interrompida manualmente.
fonte
fonte