Pourquoi utiliser finalement au lieu de code après catch

Pourquoi faire ceci

} catch (SQLException sqle) { sqle.printStackTrace(); } finally { cs.close(); rs.close(); } 

Au lieu de cela

 } catch (SQLException sqle) { sqle.printStackTrace(); } rs.close(); cs.close(); 

Parce que si une exception est lancée aucun code après l’ exécution du bloc try sauf si l’exception est interceptée. Un bloc finally est toujours exécuté, peu importe ce qui se passe dans votre bloc try .

Regardez votre bloc catch – il va lancer DAOException . Donc, les déclarations après votre blocage ne seront pas exécutées même dans l’échantillon que vous avez donné . Ce que vous avez montré (en enveloppant une exception dans une autre) est un modèle commun – mais une autre possibilité est que le bloc catch lève “accidentellement” une exception, par exemple parce que l’un des appels qu’il fait échoue.

De plus, il peut y avoir d’autres exceptions que vous n’acceptez pas – soit parce que vous avez déclaré que la méthode les lance, soit parce qu’elles constituent des exceptions non vérifiées. Voulez-vous vraiment IllegalArgumentException ressources car une IllegalArgumentException été lancée quelque part?

Parce que si une exception est levée,

  • Le code de la clause finally s’exécutera à mesure que l’exception se propage vers l’extérieur, même si l’exception annule le rest de l’exécution de la méthode.

  • Le code après le bloc try / catch ne sera exécuté que si l’exception est interceptée par un bloc catch et non renvoyée.

Parce que cela garantit que le contenu du bloc finally est exécuté. Stuff après catch pourrait ne pas être exécuté, par exemple, il y a une autre exception dans le bloc catch, ce qui est très possible. Ou vous faites simplement ce que vous avez fait et lancez une exception qui enveloppe l’exception d’origine.

Selon HeadFirst Java, un bloc finally sera exécuté même si le bloc try ou catch a une déclaration de retour. Le stream saute enfin et revient pour revenir.

Le mot-clé finally garantit l’exécution du code. Dans votre exemple de base, les instructions de fermeture ne sont PAS exécutées. Dans le premier exemple, ils sont exécutés (ce que vous voulez!)

Votre deuxième approche ne fera pas les déclarations «fermées» car elle est déjà sortie de la méthode.

Si vous attrapez toutes les erreurs, il ne devrait y avoir aucune différence, sinon, seul le code inclus dans bloc sera exécuté car la séquence d’exécution du code est: Finalement, le code -> Erreur lors de l’émission. le bloc de code fonctionne comme prévu.

C’est le moyen d’éviter les fuites de ressources

Le code du bloc finally sera appelé avant que l’exception ne soit renvoyée du bloc catch. Cela garantit que tout code de nettoyage que vous avez mis dans le bloc finally est appelé. Le code en dehors du bloc finally ne sera pas exécuté.

Considérez que catch peut lancer une exception aux fonctions de niveau supérieur dans la stack d’appels. Cela mènera à l’appel final avant de lancer l’exception au niveau supérieur.

Dans http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html, cela induit en erreur (et peut-être à l’origine de la question):

The try block of the writeList method that you've been working with here opens a PrintWriter. The program should close that stream before exiting the writeList method. This poses a somewhat complicated problem because writeList's try block can exit in one of three ways.

 1. The new FileWriter statement fails and throws an IOException. 2. The list.get(i) statement fails and throws an IndexOutOfBoundsException. 3. Everything succeeds and the try block exits normally. 

La 4ème façon (une exception autre que IOException et IndexOutOfBoundsException est levée) est manquante. Le code décrit dans la page précédente ne capture que (1) et (2) avant de recourir à la dernière.

Je suis aussi nouveau sur Java et j’ai eu les mêmes questions avant de trouver cet article. La mémoire latente tend à s’attacher davantage aux exemples qu’à la théorie en général.

Le bloc finally peut ne pas toujours s’exécuter, considérez le code suivant.

 public class Tester { public static void main(Ssortingng[] args) { try { System.out.println("The main method has run"); System.exit(1); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("The finally block has run"); } } } 

Dans votre cas, je suggérerais d’emballer le code dans définitivement block dans try / catch, car ce code peut apparemment lancer une exception.

  } catch (SQLException sqle) { sqle.printStackTrace(); } finally { try { cs.close(); rs.close(); } catch (Exception e) { //handle new exception here }