Exceptions
Cours · programmation Java (école d'ingénieur), chapitre 11 · école d'ingénieur, informatique · le début du chapitre, la suite sur Adloun
Un programme qui calcule une moyenne reçoit un tableau vide ; un utilisateur tape « douze » quand on lui demande son âge ; une banque reçoit l'ordre de retirer 500 euros d'un compte qui en contient 70. Dans les trois cas, le programme ne peut pas faire ce qu'on lui demande. Il ne doit pas non plus renvoyer un résultat faux en silence : il doit signaler le problème à qui peut le traiter.
Java dispose pour cela d'un mécanisme dédié, les exceptions. Quand une méthode rencontre une situation qu'elle ne peut pas traiter, elle lève (ou lance) une exception : son exécution s'interrompt, et l'exception remonte la chaîne des appels jusqu'à un endroit du programme qui a déclaré savoir la rattraper. Ce chapitre montre comment lire une exception, la rattraper, en lever une, et en définir de nouvelles.
Objectifs du chapitre
- Lire une trace de pile et retrouver la ligne fautive.
- Rattraper une exception avec
try/catch, en traiter plusieurs, utiliserfinally. - Connaître la hiérarchie des exceptions et distinguer exceptions vérifiées et non vérifiées.
- Lever une exception (
throw), la déclarer (throws), écrire sa propre classe d'exception. - Libérer des ressources sûrement avec try-with-resources.
- Adopter les bonnes pratiques : valider les arguments, ne jamais « avaler » une exception.
11.1 Quand un programme échoue
11.1.1 Une exception non rattrapée
Voici un programme qui calcule la moyenne entière d'un tableau de notes, et qu'on appelle par erreur sur un tableau vide.
public class TracePile {
static int moyenne(int[] notes) {
int s = 0;
for (int x : notes) s += x;
return s / notes.length; // division entière par zéro si le tableau est vide
}
static void afficherBilan(int[] notes) {
System.out.println("Moyenne : " + moyenne(notes));
}
public static void main(String[] args) {
afficherBilan(new int[] {12, 15, 9});
afficherBilan(new int[] {});
System.out.println("Fin du programme"); // jamais atteint
}
}
Moyenne : 12
Exception in thread "main" java.lang.ArithmeticException: / by zero
at TracePile.moyenne(TracePile.java:6)
at TracePile.afficherBilan(TracePile.java:10)
at TracePile.main(TracePile.java:15)
Le premier appel se passe bien. Au second, la division entière 0 / 0 est impossible : la JVM lève une exception de type ArithmeticException. Personne ne la rattrape : le programme s'arrête, et la JVM affiche ce qu'on appelle une trace de pile (stack trace). « Fin du programme » n'est jamais affiché.
11.1.2 Lire une trace de pile
Méthode — lire une trace de pile
- La première ligne donne le type de l'exception (
java.lang.ArithmeticException) et son message (/ by zero). - Les lignes
atdonnent la pile des appels au moment de l'erreur, de la plus récente à la plus ancienne. La première est l'endroit exact de l'erreur : la méthodemoyenne, ligne 6 du fichier. - Les lignes suivantes disent comment on y est arrivé :
moyennea été appelée parafficherBilan(ligne 10), elle-même appelée parmain(ligne 15). - Aller voir la ligne indiquée, puis remonter la pile pour trouver où la donnée fautive (ici, le tableau vide) a été produite.
Les exceptions que l'on rencontre le plus souvent en débutant :
| exception | cause typique |
|---|---|
ArithmeticException | division entière par zéro |
ArrayIndexOutOfBoundsException | indice de tableau hors de |
StringIndexOutOfBoundsException | position hors de la chaîne (charAt, substring) |
NullPointerException | méthode appelée sur une référence null |
NumberFormatException | Integer.parseInt("douze") |
ClassCastException | transtypage vers le bas incorrect (chapitre 9) |
InputMismatchException | Scanner.nextInt() sur un texte non numérique |
StackOverflowError | récursivité sans cas de base (chapitre 4) |
11.2 Rattraper une exception
11.2.1 try et catch
try / catchL'instruction ```java
try { instructions } catch (TypeException e) { traitement } ` est ignoré. exécute les *instructions*. Si l'une d'elles lève une exception de type TypeException (ou d'une sous-classe), l'exécution du bloc try s'arrête immédiatement et le *traitement* s'exécute, la variable e désignant l'exception. Ensuite, le programme continue normalement *après* l'instruction try. Si aucune exception n'est levée, le bloc catch
Une exception est un objet comme un autre. On peut l'interroger : e.getMessage() donne son message, e.toString() son type et son message, e.printStackTrace() affiche la trace de pile.
La suite du cours est sur Adloun
Le chapitre en entier, formules et figures comprises, avec le tuteur, les fiches, les QCM et les exercices.
Lire la suite du coursEn accès libre, sans inscription.