Le try-catch-finally (capture)

Objectifs

  • Comprendre comment utiliser les trois composants du bloc try-catch-finally du gestionnaire d'exception pour la capture et la gestion des exceptions

Mise en situation

Nous voulons capter les exceptions afin de les gérer et permettre au programme de poursuivre son cours normalement, grâce à try-catch-finally.

Les mots-clés Try, Catch et Finally (capture)

L'instruction try est utilisée pour entourer le code susceptible de lever une exception. Elle doit être utilisée dans la méthode.

Le bloc try doit être suivi soit par catch, soit par finally ou les deux. Cela signifie que nous ne pouvons pas utiliser try tout seul.

L'instruction catch permet de définir un bloc de code à exécuter si une erreur se produit dans le bloc try.

Il doit être précédé du bloc try, ce qui signifie que nous ne pouvons pas utiliser le bloc catch seul. Il peut être suivi d'un bloc finally ou pas.

L'instruction finally : elle permet de spécifier un bloc de code qui doit être exécuté dans tous les cas, avec ou sans exception. Cela peut être utile, généralement dans les scénarios où vous utilisez des ressources (base de données, entrées/sorties de fichiers...).

Elle est toujours précédé des blocs try et/ou catch et ne peut donc pas s'utiliser toute seule dans le cadre de la gestion des exceptions.

SyntaxeMots-clés try-catch : toujours par paires

Une méthode intercepte une exception en utilisant une combinaison des mots-clés try et catch.

Le mot-clé try est utilisé pour entourer le code susceptible de lever une exception. Il doit être utilisé dans la méthode.

Le bloc catch est utilisé pour gérer l'exception en déclarant le type d'exception dans le paramètre. L'exception déclarée doit être l'exception de classe parente (c'est-à-dire, Exception) ou le type d'exception généré. Cependant, la bonne approche consiste à déclarer le type d'exception générée.

1
try {
2
  //  Block de code pour exécuter du code qui pourrait lever une exception
3
}
4
catch(Exception e) {
5
  //  Block de code pour gérer les exceptions captées
6
}

Le bloc catch doit être utilisé uniquement après le bloc try. Vous pouvez utiliser plusieurs blocs catch avec un seul bloc try.

Si une exception se produit au niveau de l'instruction particulière du bloc try, le reste du code de bloc ne s'exécutera pas. Il est donc recommandé de ne pas conserver le code dans le bloc try qui ne lèvera pas d'exception.

Exemple

On essaie d'afficher le dixième élément d'une liste qui n'en compte que 3.

1
public class Main {
2
    public static void main(String[ ] args) {
3
        int[] myNumbers = {1, 2, 3};
4
        System.out.println(myNumbers[10]); // error!
5
    }
6
}
1
C:\>javac Main.java
2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3
3
	at exceptions.Main.main(Main.java)

Le programme vient de générer une exception de dépassement de la taille de tableau : ArrayIndexOutOfBoundsException.

Nous pouvons utiliser try, catch pour attraper l'erreur et exécuter du code pour gérer l'exception ArrayIndexOutOfBoundsException comme suit :

1
public class Main {
2
    public static void main(String[ ] args) {
3
        try {
4
            int[] myNumbers = {1, 2, 3};
5
            System.out.println(myNumbers[10]); // error!
6
        } catch (ArrayIndexOutOfBoundsException exception) {
7
            System.out.println("Nous venons ici de capturer l'exception ArrayIndexOutOfBoundsException et permettons ainsi au programme de ne pas s'arrêter brusquement");
8
        }
9
    }
10
}
1
C:\>javac Main.java
2
Nous venons ici de capturer l'exception ArrayIndexOutOfBoundsException et permettons ainsi au programme de ne pas s'arrêter brusquement

SyntaxeTry-catch-finally

Parfois, nous avons du code qui doit s'exécuter indépendamment du fait qu'une exception se produise, et c'est là qu'intervient le mot-clé finally .

1
try {
2
  //  Block de code pour exécuter du code qui pourrait lever une exception
3
}
4
catch(Exception e) {
5
  //  Block de code pour gérer les exceptions captées
6
}
7
finally {
8
 //   Block de code à exécuter, après try...catch, quel que soit le résultat:
9
}

En général, les programmes se présenteront comme suit :

1
try {
2
    ExecuteMyCode();
3
}
4
catch (Exception exception){
5
    DoSomethingWithException(exception);
6
} finally {
7
    AlwaysExecuteMe();
8
}

Exemple

1
public class Main {
2
    public static void main(String[ ] args) {
3
        try {
4
            int[] myNumbers = {1, 2, 3};
5
            System.out.println(myNumbers[10]); // error!
6
        } catch (ArrayIndexOutOfBoundsException exception) {
7
            System.out.println("Nous venons ici de capturer l'exception ArrayIndexOutOfBoundsException et permettons ainsi au programme de ne pas s'arrêter brusquement");
8
        } finally {
9
						 System.out.println("Je me montrerai quoi qu'il arrive avant");
10
				}
11
    }
12
}
1
C:\>javac Main.java
2
Nous venons ici de capturer l'exception ArrayIndexOutOfBoundsException et permettons ainsi au programme de ne pas s'arrêter brusquement
3
Je me montrerai quoi qu'il arrive avant

RemarqueCapture de plusieurs exceptions

Parfois, le code peut lever plus d'une exception, nous aurons donc autant de blocs catch séparés pour un bloc try :

1
try {
2
    ExecuteMyCode();
3
} catch (InvalidOperationException ioe) {
4
    DoSomethingWithException(ioe);
5
} catch (ArgumentException ae) {
6
    DoSomethingWithException(ae);
7
} finally {
8
    AlwaysExecuteMe();
9
}

On peut aussi attraper plusieurs exceptions dans un même bloc catch lorsque nous savons que la façon dont nous traiterons ces erreurs sera la même,

1
try {
2
    ExecuteMyCode();
3
} catch (InvalidOperationException | ArgumentException exception) {
4
   DoSomethingWithException(exception);
5
} finally {
6
    AlwaysExecuteMe();
7
}

RemarqueTry imbriqué

Parfois, une partie d'un bloc peut provoquer une erreur et le bloc entier lui-même peut provoquer une autre erreur. Dans de tels cas, les gestionnaires d'exceptions doivent être imbriqués.

1
try {
2
		try {
3
				ExecuteThis();
4
		} catch (ThisException e) {
5
				DoSomethongWithThisException();
6
		}
7
		try {
8
				ExecuteThat();
9
		} catch (ThatException e) {
10
				DoSomethongWithThatException();
11
		}
12
    ExecuteMyCode();
13
} catch (InvalidOperationException | ArgumentException exception) {
14
   DoSomethingWithException(exception);
15
} finally {
16
    AlwaysExecuteMe();
17
}

SyntaxeÀ retenir

Cette section décrit comment utiliser les trois composants du gestionnaire d'exception : les blocs try, catch et finally.

  • L'instruction try permet de définir un bloc de code à tester pour les erreurs lors de son exécution.

  • L'instruction catch permet de définir un bloc de code à exécuter si une erreur se produit dans le bloc try.

  • L'instruction finally permet de spécifier un bloc de code qui doit être exécuté dans tous les cas, avec ou sans exceptions.

On a aussi vu qu'on pouvait faire des captures multiples et des blocs de try imbriqués.