Bonjour ! Dans la leçon précédente, nous avons appris à identifier les différents types d'erreurs en Java en explorant la hiérarchie des exceptions. Vous savez maintenant faire la distinction essentielle entre les exceptions vérifiées (checked) et non-vérifiées (unchecked), ce qui est la base pour écrire du code robuste.
Aujourd'hui, nous passons de la théorie à la pratique. Savoir identifier une erreur est une chose, mais savoir comment la maîtriser pour que votre application ne plante pas en est une autre. L'objectif de cette leçon est donc de vous apprendre à gérer activement les exceptions à l'aide des trois mots-clés fondamentaux : try, catch et finally. C'est une compétence absolument critique pour un développeur backend, car elle garantit que vos applications peuvent gérer les imprévus avec élégance sans s'arrêter brutalement.
1. Le bloc try-catch : Intercepter une exception
Imaginez une portion de votre code qui est "à risque" : une division mathématique, une conversion de type, un accès à un tableau. Si une erreur se produit à cet endroit, par défaut, le programme s'arrête net et affiche une trace d'erreur (la stack trace) dans la console. Ce n'est pas un comportement acceptable pour une application professionnelle.
Le mécanisme try-catch permet de "surveiller" ce code à risque.
- Le code potentiellement dangereux est placé dans un bloc
try. - Si une exception se produit dans le bloc
try, l'exécution de ce bloc s'arrête immédiatement et Java cherche un bloccatchcorrespondant. - Le bloc
catchest un gestionnaire d'erreur : il définit le code à exécuter pour "rattraper" l'erreur et permettre au programme de continuer son exécution.
Les exceptions - Apprenez à programmer en Java - Zeste de Savoir
L'article "Les exceptions" sur Zeste de Savoir illustre parfaitement ce concept avec un exemple simple de division par zéro.
Lisez la section "Le bloc try{...} catch{...}". Observez bien la différence de comportement du programme avant et après l'introduction du bloc try-catch. Notez comment l'utilisation de catch permet au programme d'afficher "coucou toi !", ce qui était impossible lorsque l'exception n'était pas gérée. Concentrez-vous aussi sur l'utilisation de la méthode e.getMessage() pour obtenir une description de l'erreur.
Pour voir ce mécanisme en action, la vidéo suivante montre le flux d'exécution de manière très visuelle.
Apprendre Java #14 Exception (try catch finally)
La vidéo "Apprendre Java #14" de la chaîne JirAWS explique le fonctionnement du try-catch avec une analogie parlante.
Regardez ce passage qui montre le flux de contrôle avec et sans erreur : Démonstration du try-catch : Faites bien la distinction entre le cas où la division réussit (le catch est ignoré) et le cas où elle échoue (le catch est exécuté). Notez que la vidéo utilise error.toString() (implicitement) et mentionne la stack trace, tandis que l'article utilisait e.getMessage(). En pratique : e.printStackTrace(): Très utile pendant le développement pour déboguer. Elle imprime la pile d'appels complète de l'erreur. e.getMessage(): Utile pour obtenir un message d'erreur descriptif que vous pourriez, par exemple, logger ou afficher à l'utilisateur de manière contrôlée.
2. Visualiser le flux d'exécution
Le concept peut être résumé par le diagramme de flux suivant. Il montre clairement la bifurcation que prend votre programme lorsqu'une exception est levée.

3. Gérer plusieurs types d'exceptions
Un même bloc try peut potentiellement lever plusieurs types d'exceptions différents. Par exemple, un traitement sur un tableau pourrait lever une ArrayIndexOutOfBoundsException si l'index est invalide, ou une NumberFormatException si vous essayez de convertir un élément non numérique en int.
Java offre deux manières de gérer cela.
Approche 1 : Plusieurs blocs catch
Vous pouvez chaîner plusieurs blocs catch, chacun spécialisé dans la capture d'un type d'exception particulier. C'est utile si vous voulez effectuer un traitement différent pour chaque type d'erreur.
try {
// Code pouvant lever plusieurs types d'exceptions
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Erreur : l'index du tableau est en dehors des limites.");
} catch (NumberFormatException e) {
System.out.println("Erreur : impossible de convertir la chaîne en nombre.");
}
Approche 2 : Le multi-catch (depuis Java 7)
Si le traitement de l'erreur est identique pour plusieurs types d'exceptions, vous pouvez les regrouper dans un seul bloc catch en utilisant l'opérateur | (pipe). C'est plus concis et évite la duplication de code.
try {
// Code pouvant lever plusieurs types d'exceptions
} catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
System.out.println("Une erreur est survenue lors du traitement des données : " + e.getMessage());
}
La vidéo suivante démontre très bien ces deux approches.
APPRENDRE LE JAVA #13 - LES EXCEPTIONS
La vidéo de Graven - Développement sur les exceptions montre comment gérer plusieurs erreurs.
Regardez ce segment pour voir comment attraper plusieurs exceptions : Attraper plusieurs erreurs : L'auteur montre d'abord comment utiliser deux blocs catch distincts, puis comment les combiner avec l'opérateur |. C'est une technique très courante en développement.
4. Le bloc finally : Le filet de sécurité
Que se passe-t-il si vous avez besoin d'exécuter une action quoi qu'il arrive, qu'une exception ait été levée ou non ? C'est le rôle du bloc finally.
Le code placé dans un bloc finally est garanti d'être exécuté :
- Après le
try, si aucune exception ne s'est produite. - Après le
catch, si une exception a été attrapée et gérée. - Juste avant que le programme ne s'arrête, si une exception non gérée a été levée dans le
try.
À quoi ça sert ?
Son utilité principale est de libérer des ressources. En développement backend, vous manipulerez constamment des ressources externes : connexions à des bases de données, fichiers sur le disque, connexions réseau. Ces ressources doivent être fermées proprement pour éviter les fuites de mémoire ou de connexions. Le bloc finally est l'endroit parfait pour s'assurer que databaseConnection.close() ou file.close() soit appelé, même si une erreur a eu lieu pendant leur utilisation.
Apprendre Java #14 Exception (try catch finally)
La vidéo de JirAWS introduit simplement mais efficacement le bloc finally.
Le bloc finally : Ce passage explique la règle d'or : le code dans finally s'exécute systématiquement.
L'article de Zeste de Savoir, que nous avons déjà consulté, renforce cette idée en mentionnant explicitement les cas d'usage professionnels.
Les exceptions - Apprenez à programmer en Java - Zeste de Savoir
Cet article donne le "pourquoi" derrière le finally.
Retournez sur la page de Zeste de Savoir et lisez la partie qui introduit le mot-clé finally (juste après la première section sur try-catch). Retenez bien cette phrase : "Cela est surtout utilisé lorsque vous devez vous assurer d’avoir fermé un fichier, clos votre connexion à une base de données ou un socket". C'est un concept fondamental que nous réutiliserons massivement.
5. Exercice pratique
Mettons tout cela en pratique. Voici une méthode. Sans gestion des exceptions, elle est fragile et peut planter pour deux raisons. Votre mission est de la rendre robuste en utilisant try, catch (multi-catch) et finally.
Code de départ :
public class Parser {
public static void parseAndPrint(String[] data, int index) {
// Début du bloc à sécuriser
String value = data[index];
int number = Integer.parseInt(value);
System.out.println("Le nombre est : " + number);
// Fin du bloc à sécuriser
}
public static void main(String[] args) {
String[] testData = {"10", "20", "trente", "40"};
// Test 1 : devrait fonctionner
parseAndPrint(testData, 1);
// Test 2 : devrait lever NumberFormatException
parseAndPrint(testData, 2);
// Test 3 : devrait lever ArrayIndexOutOfBoundsException
parseAndPrint(testData, 5);
}
}
Votre objectif :
- Modifiez la méthode
parseAndPrintpour y ajouter un bloctry-catch-finally. - Le bloc
trydoit contenir le code existant de la méthode. - Utilisez un seul bloc
catch(multi-catch) pour gérer à la foisNumberFormatExceptionetArrayIndexOutOfBoundsException. Ce bloc doit afficher un message d'erreur générique comme "Erreur de traitement des données." - Le bloc
finallydoit toujours afficher le message "Fin de l'opération de parsing.".
Cliquez ici pour voir la solution
public class Parser {
public static void parseAndPrint(String[] data, int index) {
try {
String value = data[index];
int number = Integer.parseInt(value);
System.out.println("Le nombre est : " + number);
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
// Gère les deux types d'erreurs avec un seul bloc.
System.out.println("Erreur de traitement des données : " + e.getMessage());
} finally {
// Ce bloc est toujours exécuté.
System.out.println("Fin de l'opération de parsing.");
System.out.println("-----------------------------");
}
}
public static void main(String[] args) {
String[] testData = {"10", "20", "trente", "40"};
System.out.println("Test 1 :");
parseAndPrint(testData, 1); // Succès
System.out.println("Test 2 :");
parseAndPrint(testData, 2); // Erreur de format de nombre
System.out.println("Test 3 :");
parseAndPrint(testData, 5); // Erreur d'index
}
}
Résultat attendu dans la console :
Test 1 :
Le nombre est : 20
Fin de l'opération de parsing.
-----------------------------
Test 2 :
Erreur de traitement des données : For input string: "trente"
Fin de l'opération de parsing.
-----------------------------
Test 3 :
Erreur de traitement des données : Index 5 out of bounds for length 4
Fin de l'opération de parsing.
-----------------------------
Conclusion
Félicitations ! Vous maîtrisez désormais le mécanisme de base de la gestion des exceptions en Java. Vous savez comment empêcher votre programme de s'arrêter brutalement et comment garantir que des actions de nettoyage cruciales soient toujours exécutées.
Les points clés à retenir :
- Le bloc
tryisole le code à risque. - Le bloc
catchintercepte et gère une exception spécifique, permettant au programme de continuer. - On peut gérer plusieurs types d'exceptions avec des
catchmultiples ou un multi-catch (|). - Le bloc
finallycontient le code qui doit toujours s'exécuter, idéalement pour la libération de ressources.
Maintenant que vous savez "attraper" les exceptions, la prochaine leçon explorera l'autre facette de la gestion des erreurs : comment et pourquoi nous voudrions parfois lancer nos propres exceptions ou propager celles que nous recevons. Nous découvrirons également une syntaxe plus moderne, le try-with-resources, qui simplifie grandement la gestion des ressources que nous avons évoquée avec finally.