• 15 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 28/01/2019

Catchez votre première exception

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Vous avez remarqué, si votre utilisateur ne saisit pas un chiffre valide dans le terminal, votre programme plante. Si vous essayez d'accéder à une case qui n'existe pas dans un tableau, il y aussi une erreur.

Ces erreurs sont en fait un comportement prévu par Java : les exceptions ! Nous allons voir dans ce chapitre, comment les utiliser pour que notre programme les gère.

Pour récupérer une version propre du projet prêt pour ce chapitre, vous pouvez importer le projet git suivant : MyMenu - Step 8

Les exceptions

Une exception est un cas extraordinaire dans un programme, un cas qui n'est pas censé arriver. Voici quelques exemples :

  • Une méthode est destinée à récupérer un nombre saisi par l'utilisateur. La saisie est un texte et non un nombre comme prévu.

  • Vous avez un tableau à 7 cases et vous essayez d'accéder à la 11ème.

  • Vous divisez un nombre par  0 . C'est une erreur d'arithmétique.

  • Vous essayez de lire dans un fichier qui n'existe pas.

Quand une erreur intervient vous avez un message de ce type :

jshell> 5 / 0
|  java.lang.ArithmeticException thrown: / by zero
|        at (#58:1)

Le message nous précise que si l'on fait  5 / 0  on a une exception de type  java.lang.ArithmeticException.

C'est important de connaître le type d'exception. Cela va permettre de catcher l'exception, ce qui signifie, dire à Java : si ce type d'exception arrive, alors adopte tel comportement.

Cela s'écrit sous la forme :

try {
	code pouvant générer l'exception
} catch (TypeException nom) {
	code à exécuter si l'exception intervient
}

On peut essayer directement dans JShell :

jshell> try {
   ...> int i = 5 / 0;
   ...> } catch (ArithmeticException e) {
   ...> System.out.println("Division par 0");
   ...> }

Division par 0

L'exception ne s'est pas affichée. Seule la phrase  "Division par 0"  a été affichée.

Limitez les erreurs de saisie

Dans notre programme, si on saisit du texte à la place d'un nombre, on obtient l'erreur suivante :

Combien souhaitez vous commander de menu ?
str
Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:860)
    at java.base/java.util.Scanner.next(Scanner.java:1497)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2161)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2115)
    at com.ocr.anthony.Main.main(Main.java:46)

Process finished with exit code 1

 C'est la première ligne qui nous intéresse :  InputMismatchException

Nos saisies s'effectuent dans les méthodes  askSomething  et  runMenus , il n'y a donc que ces méthodes à modifier. Plutôt pratique, non ?

Dans notre test, nous allons saisir du texte et vérifier que la phrase d'erreur est bien affichée.

@Test
public void Given_TextResponse_When_CallingAskQuestion_Then_DisplayErrorSentence() {
    System.setIn(new ByteArrayInputStream(String.format("texte%n1%n").getBytes()));
    order = new Order();
    String[] responses = {"BMW", "Audi", "Mercedes"};
    order.askSomething("voiture", responses);
    String[] output = outContent.toString().replace("\r\n", "\n").split("\n");
    assertEquals("Vous n'avez pas choisi de voiture parmi les choix proposés", output[5]);
}
@Test
public void Given_BadMenusQuantityInStandardInput_When_MenusIsRun_Then_DisplayErrorSentence() {
    System.setIn(new ByteArrayInputStream(String.format("texte%n1%n1%n2%n3%n").getBytes()));
    order = new Order();
    order.runMenus();
    String[] output = outContent.toString().replace("\r\n", "\n").split("\n");
    assertEquals("Vous devez saisir un nombre, correspondant au nombre de menus souhaités", output[1]);
}

Voici le code modifié pour  askSomething  et  runMenus  :

/**
 * Display a question about a category in the standard input, get response and display it
 * @param category the category of the question
 * @param responses available responses
 * @return the number of the selected choice
 */
public int askSomething(String category, String[] responses) {
        System.out.println("Choix " + category);
        for (int i = 1; i <= responses.length; i++)
            System.out.println(i + " - " + responses[i - 1]);
        System.out.println("Que souhaitez-vous comme " + category + "?");
        int nbResponse = 0;
        boolean responseIsGood;
        do {
            try {
                nbResponse = sc.nextInt();
                responseIsGood = (nbResponse >= 1 && nbResponse <= responses.length);
            } catch (InputMismatchException e) {
                sc.next();
                responseIsGood = false;
            }
            if (responseIsGood) {
                String choice = "Vous avez choisi comme " + category + " : " + responses[nbResponse - 1];
                orderSummary += choice + "%n";
                System.out.println(choice);
            } else {
                boolean isVowel = "aeiouy".contains(Character.toString(category.charAt(0)));
                if (isVowel)
                    System.out.println("Vous n'avez pas choisi d'" + category + " parmi les choix proposés");
                else
                    System.out.println("Vous n'avez pas choisi de " + category + " parmi les choix proposés");
            }
        } while (!responseIsGood);
        return nbResponse;
}
public void runMenus() {
    System.out.println("Combien souhaitez vous commander de menu ?");
    int menuQuantity = -1;
    boolean responseIsGood;
    do {
        try {
            menuQuantity = sc.nextInt();
            responseIsGood = true;
        } catch (InputMismatchException e) {
            sc.next();
            System.out.println("Vous devez saisir un nombre, correspondant au nombre de menus souhaités");
            responseIsGood = false;
        }
    } while (!responseIsGood);
    orderSummary = "Résumé de votre commande :%n";
    for (int i = 0; i < menuQuantity; i++) {
        orderSummary += "Menu " + (i + 1) + ":%n";
        runMenu();
    }
    System.out.println("");
    System.out.println(String.format(orderSummary));
}
Exemple de certificat de réussite
Exemple de certificat de réussite