Est-il sensé de faire «essayer-enfin» sans «attraper»?

127

J'ai vu du code comme celui-ci:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

Je pensais qu'il tryétait censé avoir un catch?

Pourquoi ce code le fait-il de cette façon?

glanden
la source
1
il assure le nettoyage comme d'autres réponses mentionnées, en particulier pour les fopen
descripteurs

Réponses:

182

Ceci est utile si vous souhaitez que la méthode en cours d'exécution lève toujours l'exception tout en permettant le nettoyage approprié des ressources. Voici un exemple concret de gestion de l'exception à partir d'une méthode d'appel.

public void yourOtherMethod() {
    try {
        yourMethod();
    } catch (YourException ex) {
        // handle exception
    }
}    

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}
Taylor Leese
la source
17
couramment utilisé avec des verrous comme dans: lock.lock (); essayez enfin {/ * verrouillé * /} {lock.unlock ()}
min
Que se passe-t-il si une exception est finalement lancée à l'intérieur?
barth
1
@barth Lorsqu'il n'y a pas de catchbloc, l'exception lancée finallysera exécutée avant toute exception dans le trybloc. Donc, s'il y a deux exceptions une dans tryet une dans finallyla seule exception qui sera levée est celle dans finally. Ce comportement n'est pas le même en PHP et Python car les deux exceptions seront lancées en même temps dans ces langages et l'ordre des exceptions est d' tryabord un alors finally.
Pluie le
72

C'est là parce que le programmeur voulait s'assurer que cela db.cleanup()est appelé même si le code à l'intérieur du bloc try lève une exception. Toutes les exceptions ne seront pas gérées par ce bloc, mais elles ne seront propagées vers le haut qu'après l'exécution du bloc finally.

Matti Virkkunen
la source
23
+1 Exactement. Le tryest juste là pour permettre le finally. Les exceptions ne sont pas capturées.
zockman
2
+1 pour indiquer clairement que l'exception continue dans la pile jusqu'à ce qu'elle soit capturée. Merci
Code Jockey
20

Pourquoi ce code le fait-il de cette façon?

Parce qu'apparemment le code ne sait pas comment gérer les exceptions à ce niveau. C'est bien - tant que l'un des appelants le fait, c'est-à-dire tant que l'exception est finalement gérée quelque part.

Souvent, le code de bas niveau ne peut pas réagir correctement aux exceptions car l'utilisateur doit être notifié, ou l'exception doit être enregistrée ou une autre stratégie doit être essayée. Le code de bas niveau remplit une seule fonction et ne connaît pas la prise de décision de plus haut niveau.

Mais le code doit toujours nettoyer ses ressources (car si ce n'est pas le cas, elles fuiraient), il le fait donc dans la finallyclause, en s'assurant que cela se produit toujours , qu'une exception soit levée ou non.

Konrad Rudolph
la source
2

Le bloc finally garantit que même lorsqu'une RuntimeException est lancée (peut-être en raison d'un bogue dans le code appelé), l' db.cleanup()appel sera effectué.

Ceci est également souvent utilisé pour éviter une imbrication excessive:

try
{
    if (foo) return false;
    //bla ...
    return true;
}
finally
{
    //clean up
}

Surtout quand il y a de nombreux points auxquels la méthode retourne, cela améliore la lisibilité car tout le monde peut voir que le code de nettoyage est appelé dans tous les cas.

FRotthowe
la source
0

Le code le fait pour s'assurer que la base de données est fermée.
Habituellement, la façon dont vous le feriez est de mettre tout votre code d'accès à la base de données dans le bloc try, puis de passer un appel pour fermer la base de données dans le bloc finally.
La façon dont try ... enfin fonctionne, signifie que le code du bloc try est exécuté et que le code du bloc finally est exécuté lorsque cela se termine ... quoi qu'il arrive.
À moins que l'ordinateur ne soit arraché du mur, le dernier s'exécutera.
Cela signifie que même si une exception est appelée et que la méthode prend trois ans à s'exécuter, elle ira toujours dans le bloc finally et la base de données sera fermée.

chustar
la source
0

Si l'un des codes du bloc try peut lever une exception vérifiée, il doit apparaître dans la clause throws de la signature de méthode. Si une exception non vérifiée est levée, elle est exclue de la méthode.

Le bloc finally est toujours exécuté, qu'une exception soit levée ou non.

VASEE THINESH
la source