Adloun

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, utiliser finally.
  • 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 at donnent 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éthode moyenne, ligne 6 du fichier.
  • Les lignes suivantes disent comment on y est arrivé : moyenne a été appelée par afficherBilan (ligne 10), elle-même appelée par main (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 :

exceptioncause typique
ArithmeticExceptiondivision entière par zéro
ArrayIndexOutOfBoundsExceptionindice de tableau hors de
StringIndexOutOfBoundsExceptionposition hors de la chaîne (charAt, substring)
NullPointerExceptionméthode appelée sur une référence null
NumberFormatExceptionInteger.parseInt("douze")
ClassCastExceptiontranstypage vers le bas incorrect (chapitre 9)
InputMismatchExceptionScanner.nextInt() sur un texte non numérique
StackOverflowErrorrécursivité sans cas de base (chapitre 4)

11.2 Rattraper une exception

11.2.1 try et catch

Définition 11.1Bloc try / catch

L'instruction ```java

try { instructions } catch (TypeException e) { traitement } ` 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 est ignoré.

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 cours

En accès libre, sans inscription.

Exercices corrigés de ce chapitre

Lire la suite du cours →