12.La gestion des exceptions




Fig. 12.1 La hiérarchie des erreurs

12.2    La classe Exception


12.2.1    Le bloc try/catch 


try {
    …                 //code surveillé qui peut générer des exceptions
}
catch(type1 id1) {     // on peut avoir zero (à condition qu'il  y a "finally") ou plusieurs "catching" blocs
    …                 //traite les exceptions de type type1 dans le bloc surveillé
}
catch(type2 id2) {                  
         ...  //traite les exceptions de type type2
}

finally {             //on peut avoir zero ou un "finally" blocs
    …                 //toujours executé, aucune importance s'il y a eu lieu exception ou pas
}


Fig. 12.2 Call stack

Fig.12.3 Recherche d'un try/catch bloc

Exemple  -  La somme de deux entiers introduits dans les champs texte 
exception non gérée:

import java.util.Scanner;
public class Sum {
    public static void main(String[] arg) {
        Scanner in = new Scanner(System.in);
        int first,second;
        String rez;
        System.out.println ("Addition of two integers\n");
        System.out.print("please input the first integer: ");
        first = getInt(in);
        System.out.print("please input the second integer: ");
        second = getInt(in);
        rez="\nthe sum of "+first+" and "+second+" is: "+(first+second);
        System.out.println(rez);
    }
    public static int getInt(Scanner in) {
        return Integer.parseInt(in.nextLine());
    }
}


exception gérée:

import java.util.Scanner;
public class SumExc {
    public static void main(String[] arg) {
        Scanner in = new Scanner(System.in);
        int first=0,second=0;
        String rez="";
        System.out.println ("Addition of two integers\n");
        try {
            System.out.print("please input the first integer: ");
            first = getInt(in);       
            System.out.print("please input the second integer: ");
            second = getInt(in);
            rez="\nthe sum of "+first+" and "+second+" is: "+(first+second);
        }
        catch(java.lang.NumberFormatException e1) {
            rez="Both must be integers! The program terminated!";
        }
        finally {
            System.out.println(rez);
        }
    }
    public static int getInt(Scanner in) {       //no catch here
        return Integer.parseInt(in.nextLine());
    }
}


 12.2.2    Instruction throw

  if( q = = null)
        throw new NullPointerException();

 12.2.3    Créer son propre type d'exception

Pour créer son propre type d'exception, il faut écrire une classe héritant de la classe Exception ou une de ses classes dérivées

class NoNote extends Exception{
    String message;
    NoNote(String message){
        this.message = message;
        System.out.println(message);
    }
}

Les exceptions sont gérées dans la méthode où elles se produisent:

import java.util.*;
public class Exc3 {
    public static void main(String arg[]){
        System.out.println("Note: "+Note());
    }
    static int Note(){
        Scanner sc = new Scanner(System.in);
        boolean ok;
        int note=-1;
        do{
            ok = true;
            System.out.print("next note:");
            try {
                note = sc.nextInt();
            }
            catch(InputMismatchException ex1) {
                System.out.println ("the note must be integer - try again");
                sc.nextLine();
                ok=false;
                continue;
            }

            try{
                if((note>6)||(note <2)){
                    throw new NoNote("outside [2,6] - try again");
                }
            }
            catch(NoNote ex){
                ok = false;
            }
        }while(!ok);
        sc.close();
        return note;
    }
}

Les exceptions sont gérées en dehors de la méthode où elles se produisent:

import java.util.*;
public class Exc4 {
    public static void main(String arg[]){
        boolean ok;
        Scanner sc = new Scanner(System.in);
        do{
            ok = true;
            try {
                System.out.println("Note: "+Note(sc));
            }
            catch(InputMismatchException ex1) {
                System.out.println ("the note must be integer - try again");
                sc.nextLine();
                ok=false;
            }
            catch (NoNote ex2) {
                ok=false;
            }
        }while(!ok);
    }
    static int Note(Scanner sc) throws NoNote{        //checked exception
        int note;
        System.out.print("next note:");
        note = sc.nextInt();
        if((note>6)||(note <2)){
            throw new NoNote("outside [2,6] - try again");
        }
        return note;       
    }
}


 12.2.4    Catégories des exceptions


On peut diviser les exceptions en deux catégories - "unchecked" et "checked". Les premières sont des exceptions dont la classe de base est "RuntimeException" (dérivée de "Exception"). Il n'est pas obligatoire de gérer ces exceptions.

Exemple - division à zéro sans traiter l'exception ArithmeticException (elle est "unchecked").

public class Exc1 {
    public static void main(String arg[]){
        System.out.println("rez:"+func(5,0));
    }
    static int func(int a, int b){
        return a/b;
    }
}

L'exception est traitée

public class Exc2 {
    public static void main(String arg[]){
        try{
            System.out.println("rez:"+func(5,0));
        }
        catch(ArithmeticException ex){
            System.out.println("divide by zero");
        }
    }
    static int func(int a, int b){ return a/b; }
}

Par contre le compilateur refusera systématiquement de compiler  une méthode capable de provoquer une "checked" exception, si cette exception n'est pas rattrapée (par try/catch ) ou tout du moins signalée comme susceptible de générer ce type d'exceptions (par le mot clé throws).

static int Note() throws NoNote{
    Scanner sc = new Scanner(System.in);
    int note;
    System.out.print("next note:");
    note = sc.nextInt();
   
if((note>6)||(note <2))
                    throw new NoNote("outside [2,6]");
    return note;
}