Compte tenu de ce code, puis-je être absolument sûr que le finally
bloc s'exécute toujours, quel qu'il something()
soit?
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
la source
la source
probably
place.finally
; finalizer == lafinalize()
méthode.Réponses:
Oui,
finally
sera appelé après l'exécution des blocs de codetry
oucatch
.Les seules heures
finally
qui ne seront pas appelées sont:System.exit()
Runtime.getRuntime().halt(exitStatus)
try
orcatch
kill -9 <pid>
sous UNIXfinally
bloc va être exécuté par un thread démon et que tous les autres threads non démons se terminent avant,finally
est appeléla source
thread.stop()
n'empêche pas nécessairement l'finally
exécution du bloc.finally
bloc sera appelé après letry
bloc et avant que le contrôle ne passe aux instructions suivantes. Cela est cohérent avec le bloc try impliquant une boucle infinie et donc le bloc finalement jamais réellement invoqué.Exemple de code:
Production:
la source
finally
clause-return 2;
n'est pas autorisé (Compiler-Error).De plus, bien que ce soit une mauvaise pratique, s'il y a une instruction return dans le bloc finally, elle l'emportera sur tout autre retour du bloc normal. Autrement dit, le bloc suivant retournerait faux:
Même chose avec le lancement d'exceptions du bloc finally.
la source
Voici les mots officiels de la spécification du langage Java.
14.20.2. Exécution de try-finally et try-catch-finally
La spécification de
return
rend cela explicite:JLS 14.17 La déclaration de retour
la source
En plus des autres réponses, il est important de souligner que «finalement» a le droit de remplacer toute exception / valeur retournée par le bloc try..catch. Par exemple, le code suivant renvoie 12:
De même, la méthode suivante ne lève pas d'exception:
Alors que la méthode suivante le lance:
la source
OutOfMemoryError
? ;)return retVal
après lefinally
bloc, bien que cela suppose bien sûr que vous ayez supprimé certaines autres exceptions car le code n'aurait pas de sens autrement.J'ai essayé l'exemple ci-dessus avec une légère modification-
Le code ci-dessus génère:
C'est parce que quand
return i;
est exécutéi
a une valeur 2. Après cela, lefinally
bloc est exécuté où 12 est assigné ài
puisSystem.out
out est exécuté.Après avoir exécuté le
finally
bloc, letry
bloc renvoie 2, au lieu de renvoyer 12, car cette instruction de retour n'est pas exécutée à nouveau.Si vous déboguez ce code dans Eclipse, vous aurez l'impression qu'après l'exécution
System.out
dufinally
bloc, l'return
instruction detry
bloc est exécutée à nouveau. Mais ce n'est pas le cas. Il renvoie simplement la valeur 2.la source
i
n'était pas un objet primitif, mais un objet Entier.Voici une élaboration de la réponse de Kevin . Il est important de savoir que l'expression à renvoyer est évaluée avant
finally
, même si elle est retournée après.Production:
la source
finally
. Le calcul de la valeur de retour (printX()
ici) précède toujours.System.out.println("finally trumps return... sort of");
parSystem.out.print("finally trumps return in try"); return 42;
C'est toute l'idée d'un bloc enfin. Il vous permet de vous assurer que vous effectuez des nettoyages qui pourraient autrement être ignorés car vous revenez, entre autres, bien sûr.
Est finalement appelé indépendamment de ce qui se passe dans le bloc try (à moins que vous n'appeliez
System.exit(int)
ou que la machine virtuelle Java ne démarre pour une autre raison).la source
Une façon logique d'y penser est:
la source
enfin est toujours exécuté sauf en cas de fin anormale du programme (comme appeler System.exit (0) ..). donc, votre sysout sera imprimé
la source
De plus, un retour entraînera la suppression de toute exception. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
la source
Le bloc finally est toujours exécuté sauf en cas de fin anormale du programme, résultant soit d'un crash de la JVM, soit d'un appel à
System.exit(0)
.En plus de cela, toute valeur renvoyée à l'intérieur du bloc finally remplacera la valeur retournée avant l'exécution du bloc finally, alors faites attention à vérifier tous les points de sortie lorsque vous utilisez try enfin.
la source
Non, pas toujours un cas d'exception est // System.exit (0); avant que le bloc finalement empêche finalement d'être exécuté.
la source
Enfin est toujours exécuté, c'est tout le point, juste parce qu'il apparaît dans le code après le retour ne signifie pas que c'est comme ça qu'il est implémenté. Le runtime Java a la responsabilité d'exécuter ce code lors de la sortie du
try
bloc.Par exemple, si vous disposez des éléments suivants:
Le runtime va générer quelque chose comme ceci:
Si une exception non interceptée est levée, le
finally
bloc s'exécute et l'exception continue de se propager.la source
En effet, vous avez affecté la valeur de i à 12, mais vous n'avez pas renvoyé la valeur de i à la fonction. Le code correct est le suivant:
la source
Parce qu'un bloc finally sera toujours appelé à moins que vous n'appeliez
System.exit()
(ou que le thread ne plante).la source
De manière concise, dans la documentation Java officielle (cliquez ici ), il est écrit que -
la source
CONTRIBUTION:
PRODUCTION:
la source
Oui, il sera appelé. C'est tout l'intérêt d'avoir un mot-clé enfin. Si sauter hors du bloc try / catch pouvait simplement sauter le bloc finalement, c'était la même chose que de mettre System.out.println en dehors du try / catch.
la source
Oui, enfin le bloc est toujours exécuté. La plupart des développeurs utilisent ce bloc pour fermer la connexion à la base de données, l'objet d'ensemble de résultats, l'objet d'instruction et les utilisent également dans l'hibernation java pour annuler la transaction.
la source
PAS TOUJOURS
La spécification du langage Java décrit comment
try
-catch
-finally
ettry
-catch
blocs fonctionnent à 14.20.2En aucun endroit , il précise que le
finally
bloc est toujours exécuté. Mais pour tous les cas où latry
-catch
-finally
ettry
- desfinally
blocs complets , il ne précise que , avant la finfinally
doit être exécuté.Le JLS ne garantit pas que FIN est exécuté après CODE . Le JLS garantit que si CODE et NEXT sont exécutés, FIN sera toujours exécuté après CODE et avant NEXT .
Pourquoi le JLS ne garantit-il pas que le
finally
bloc est toujours exécuté après letry
bloc? Parce que c'est impossible. Il est peu probable mais possible que la JVM soit abandonnée (kill, crash, power off) juste après la fin dutry
bloc mais avant l'exécution dufinally
bloc. Il n'y a rien que le JLS puisse faire pour éviter cela.Ainsi, tout logiciel qui, pour son bon comportement, dépend des
finally
blocs toujours exécutés une fois leurstry
blocs terminés est buggé.return
les instructions dans letry
bloc ne sont pas pertinentes pour ce problème. Si l'exécution atteint le code après letry
-catch
-finally
il est garanti que lefinally
bloc aura été exécuté avant, avec ou sansreturn
instructions à l'intérieur dutry
bloc.la source
Oui, il sera. Peu importe ce qui se passe dans votre bloc try ou catch, à moins que System.exit () ne soit appelé ou que JVM ne plante. s'il y a une instruction de retour dans le (s) bloc (s), finalement sera exécutée avant cette instruction de retour.
la source
Oui, il sera. Le seul cas où ce ne sera pas le cas, c'est que la JVM se ferme ou se bloque
la source
Ajouter à la réponse de @ vibhash car aucune autre réponse n'explique ce qui se passe dans le cas d'un objet mutable comme celui ci-dessous.
Sortira
la source
J'ai essayé, c'est un filetage simple.
Le
main
Thread
sera enwait
état pour toujours, doncfinally
ne sera jamais appelé ,donc la sortie de la console ne sera pas
print
String
: aprèswait()
oufinally
En accord avec @Stephen C, l'exemple ci-dessus est l'un des troisièmes cas mentionnés ici :
Ajout d'autres possibilités de boucle infinie dans le code suivant:
Cas 2: si la JVM plante en premier
Réf: Comment planter une JVM?
Cas 6: Si le
finally
bloc va être exécuté par le démonThread
et que toutes les autres sorties non démonThreads
avantfinally
sont appelées.sortie: Ceci n'imprime pas "finalement" ce qui implique que "Enfin bloquer" dans "thread démon" ne s'est pas exécuté
la source
Considérez le programme suivant:
Depuis Java 1.8.162, le bloc de code ci-dessus donne la sortie suivante:
cela signifie que l'utilisation
finally
pour libérer des objets est une bonne pratique comme le code suivant:la source
sb.setLength(0)
enfin?sb = null;
juste ajoute du code inutile. Je comprends que vous voulez dire qu'unfinally
bloc est un bon endroit pour libérer des ressources comme une connexion à une base de données ou quelque chose comme ça, mais gardez à l'esprit que votre exemple pourrait confondre les nouveaux arrivants.System.out.println("---AGAIN2---");
System.out.println(sb);
et c'est plus clair maintenant. En l'état, la sortie était contraire à votre thèse: p J'ai également ajouté à votre réponse, mais la modification doit être acceptée par un modérateur ou quelqu'un comme ça. Sinon, vous pouvez les ajouterC'est en fait vrai dans n'importe quel langage ... enfin s'exécutera toujours avant une instruction return, peu importe où ce retour est dans le corps de la méthode. Si ce n'était pas le cas, le bloc finalement n'aurait pas beaucoup de sens.
la source
En plus du point sur le retour pour remplacer finalement un retour dans le bloc try, il en va de même pour une exception. Un bloc finally qui lève une exception remplacera un retour ou une exception levée depuis le bloc try.
la source
finally
va s'exécuter et c'est sûr.finally
ne s'exécutera pas dans les cas ci-dessous:cas 1 :
Lorsque vous exécutez
System.exit()
.cas 2:
Lorsque votre JVM / Thread plante.
cas 3:
Lorsque votre exécution est arrêtée entre les deux manuellement.
la source
la source