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 levée aucun code après le bloc try
est exécuté sauf si l'exception est interceptée. Un bloc finally
est toujours exécuté quoi qu'il arrive à l'intérieur de votre bloc try
.
Regardez votre bloc catch - il va lancer DAOException
. Ainsi, les instructions après votre bloc catch ne seront pas exécutées même dans l'exemple que vous avez donné. Ce que vous avez montré (en enveloppant une exception dans une autre) est un modèle courant - mais une autre possibilité est que le bloc catch lève "accidentellement" une exception, par ex. car l'un des appels qu'il fait échoue.
De plus, il peut y avoir d'autres exceptions que vous ne faites pas intercepter - soit parce que vous avez déclaré que la méthode les lève, soit parce que ce sont des exceptions non vérifiées. Voulez-vous vraiment perdre des ressources parce qu'un IllegalArgumentException
a été jeté quelque part?
Parce que si une exception est levée,
Le code de la clause finally s'exécutera à mesure que l'exception se propagera vers l'extérieur, même si l'exception interrompt le reste de l'exécution de la méthode;
Le code après le bloc try/catch ne sera pas exécuté à moins que l'exception ne soit interceptée par un bloc catch et ne soit renvoyée.
Parce que cela garantit que les éléments du bloc finally sont exécutés. Les trucs après catch peuvent ne pas être exécutés, 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 vous lancez une exception qui enveloppe l'exception d'origine.
Selon HeadFirst Java, un bloc finally s'exécutera même si le bloc try ou catch a une instruction return. Flow saute enfin, puis revient pour revenir.
Le mot-clé finally garantit que le code est exécuté. Dans votre exemple du bas, les instructions close NE SONT PAS exécutées. Dans l'exemple du haut, ils sont exécutés (ce que vous voulez!)
Votre deuxième approche ne fera pas les déclarations "close" car elle est déjà laissée dans la méthode.
Si vous interceptez toutes les erreurs, il ne devrait pas y avoir de différence, sinon, seul le code à l'intérieur du bloc finally est exécuté car la séquence d'exécution du code est: 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é.
cela pourrait clarifier: http://www.Java2s.com/Code/Java/Language-Basics/Finallyisalwaysexecuted.htm
Dans http://docs.Oracle.com/javase/tutorial/essential/exceptions/finally.html cela est trompeur (et peut avoir provoqué 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 manière (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 à finally
.
Je suis également nouveau sur Java et j'ai eu le même questionnement avant de trouver cet article. La mémoire latente a tendance à 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(String[] 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ère d'envelopper le code à l'intérieur du bloc finalement dans try/catch, car ce code peut apparemment lever une exception.
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
try {
cs.close();
rs.close();
} catch (Exception e) {
//handle new exception here
}
considérez que le catch peut lever une exception aux fonctions de niveau supérieur dans la pile des appels. Cela mènera à l'appel final avant de lancer l'exception au niveau supérieur.