2010-07-28 4 views
36

Je n'ai jamais bien compris l'utilisation de l'instruction finally. Quelqu'un peut-il me dire quelle est la différence entre:comment utiliser enfin

try { 
    a; 
    block; 
    off; 
    statements; 
} catch (Exception e) { 
    handle; 
    exception; 
    e; 
} finally { 
    do; 
    some; 
    cleanup; 
} 

d'une part et:

try { 
    a; 
    block; 
    off; 
    statements; 
} catch (Exception e) { 
    handle; 
    exception; 
    e; 
} 
do; 
some; 
cleanup; 

autre

Répondre

35

Ils diffèrent si

  • la try -bloc complète en jetant un java.lang.Throwable qui n'est pas java.lang.Exception, par exemple parce qu'il est un java.lang.Error tel que AssertionError ou OutOfMemoryError.
  • le bloc try se termine brusquement au moyen d'un tableau de flux de commande un tel continue, break ou return
  • le bloc catch se termine brusquement (en lançant une throwable, ou en utilisant un tableau de flux de commande)

Plus Généralement, le langage java garantit qu'un bloc finally est exécuté avant la fin de l'instruction try. (Notez que si l'instruction try ne se termine pas, il n'y a aucune garantie sur le résultat final.Une instruction peut ne pas être complète pour diverses raisons, y compris l'arrêt matériel, l'arrêt du système d'exploitation, l'arrêt de machine virtuelle (par exemple System.exit) attente (Thread.suspend(), synchronized, Object.wait(), Thread.sleep()) ou d'être autrement occupé (boucles sans fin, ,,,). Alors

, un bloc finally est un meilleur endroit pour des actions de nettoyage à la fin du corps de la méthode, mais en lui-même, ne peut toujours pas garantir l'exeuction de nettoyage

7

Dans le style de codage approprié, vous ne voulez pas faire un crochet tout comme ci-dessous.

try{ 
    [some task] 
} 
catch 
{ 
} 

Ce que vous voudriez faire est d'attraper des erreurs connues spécifiques.

try{ 
    [some task] 
} 
catch(Exception ex) 
{ 
    if([known execption]) 
    [ignore] 
    else 
    throw(ex); 
} 
[Cleanup] 

Dans ce cas, votre code de nettoyage ne sera pas exécuté en cas d'erreur renvoyée. Nous ajoutons donc le dernier qui sera exécuté même si une nouvelle erreur est lancée.

try{ 
    [some task] 
} 
catch(Exception ex) 
{ 
    if([known execption]) 
    [ignore] 
    else 
    throw(ex); 
} 
finally 
{ 
    [Cleanup] 
} 
27

finally Le bloc s'exécute toujours. bloc

finally est utilisé pour le nettoyage, comme pour libérer des ressources utilisées dans try/catch, connexions db à proximité, prises à proximité, etc .. même si une exception non gérée se produit dans votre bloc try/catch.

La seule fois que le bloc finally n'exécute pas est quand system.exit() est appelé à try/catch ou une erreur se produit au lieu d'une exception.

L'erreur dans la description ci-dessus signifie que l'application Java quitte avec des conditions telles que l'erreur Out Of Memory. Je vois quelques downvotes :(pour cette raison, il semble

+2

Correction: un bloc final _is_ est exécuté lorsqu'une erreur java.lang.Error est levée.Il peut ne pas être exécuté avec succès, mais il est exécuté. ditions qui peuvent contrarier l'exécution d'un bloc finally, voir ma réponse pour une liste incomplète. – meriton

+0

Remarque: Si la JVM se ferme pendant l'exécution du code try ou catch, le bloc finally peut ne pas s'exécuter. De même, si le thread exécutant le code try ou catch est interrompu ou détruit, le bloc finally peut ne pas s'exécuter même si l'application dans son ensemble continue. - https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html – Hansa

18

La principale différence est que la section catch peut elle-même lancer une exception, sortir d'un bloc environnant, ou revenir de la méthode actuelle, dans ce cas n'est pas . exécuté

Avec un bloc finally, il est garanti que ce code sera exécuté

+0

Est-il enfin garanti d'être exécuté? http://stackoverflow.com/questions/464098/does-a-finally-block-always-run –

+0

Oui, pas en cas de System.exit(), c'est vrai. Ou, vous le savez, un crash JVM. – Dan

+2

... ou un blocage, ou ... - la vraie règle est la suivante: Un bloc finally est garanti avoir été exécuté quand/si l'instruction try- (catch) -finally est terminée. – meriton

10

il est fondamentalement une mauvaise idée de prendre toutes les exceptions -. si vous devez considérer ce qui se passera si un se propage d'exception uncaught à partir de votre try/catch ou try/catch/finally bloquer Enfin les blocs permettent yo vous nettoyer à la sortie.

aussi:

  • Le bloc catch peut jeter une exception
  • Vous pouvez revenir du bloc try

En bref, si vous voulez un peu de code à exécuter lorsque vous laissez le bloc try/catch cependant vous le quittez (mis à part le processus se terminant très dur), enfin c'est votre ami.

7

Le bloc "finally" s'exécutera toujours.

Dans votre deuxième exemple, le nettoyage ne se produirait pas si le bloc de capture renvoyait l'exception ou si une exception non interceptée se produisait dans le bloc try.

+0

Il y a de nombreuses conditions où le dernier n'est pas exécuté (c.f. ma réponse), mais vous avez raison de dire que les exceptions de lancement (ou l'utilisation d'instructions de flux de contrôle) n'en font pas partie. – meriton

3

du Forum sur this GeekInterview:

Le bloc finally est toujours exécutée lors de la sortie du bloc try. Cela garantit que le bloc finally est exécuté même si une exception inattendue se produit. Mais finalement est utile pour plus que la simple gestion des exceptions - cela permet au programmeur d'éviter que le code de nettoyage ne soit accidentellement contourné par un retour, une continuation ou un break. Mettre du code de nettoyage dans un bloc finally est toujours une bonne pratique, même si aucune exception n'est anticipée.

1

simplement une ligne d'explication:

indépendamment du fait que vous avez pris une exception ou non, les codes dans le bloc finally se sont exécutées. Le diff entre les deux pièces que vous avez donné ici est: les codes dans la pièce sans utiliser finally ne seront jamais exécutés.

pour bien comprendre finally, tout ce que vous devez savoir est que finally = garantie!

vous pouvez l'utiliser pour nettoyer, pour aider w/convivialité ou de réessayer quelque chose

0

Dans le premier exemple, le bloc finally obtient toujours exécuté même si vous avez une déclaration de retour dans la clause d'essai. La seule fois où il n'est pas exécuté est quand vous avez System.exit (0).

+0

il existe de nombreuses autres conditions où le finalement n'est pas exécuté, c.f. ma réponse (qui ne prétend pas les donner tous ...) – meriton

Questions connexes