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.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Sum extends JFrame {
    JTextField textField1,textField2,rez;
    JLabel l;
    int value1=0,value2=0,sum=0;
    Sum(){
        setLayout(new FlowLayout());
        textField1 = new JTextField(5);
        textField2 = new JTextField(5);
        textField1.addActionListener(new Enter());
        textField2.addActionListener(new Enter());
        l = new JLabel(" Type a number in each box!");
        add(l);
        rez= new JTextField(18);
        add(textField1);
        add(textField2);
        add(rez);
        textField1.setText("0");
        textField2.setText("0");
        setSize(230,150);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    class Enter implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            value1= Integer.parseInt(textField1.getText());
            value2= Integer.parseInt(textField2.getText());
            rez.setText(value1+value2+"");
        }
    }
    public static void main(String arg[]){
        new Sum();
    }
}

exception gérée:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SumEx extends JFrame {
    JTextField textField1,textField2,rez;
    JLabel l;
    int value1=0,value2=0,sum=0;
    SumEx(){
        setLayout(new FlowLayout());
        textField1 = new JTextField(5);
        textField2 = new JTextField(5);
        textField1.addActionListener(new Enter());
        textField2.addActionListener(new Enter());
        l = new JLabel(" Type a number in each box!");
        add(l);
        rez= new JTextField(18);
        add(textField1);
        add(textField2);
        add(rez);
        textField1.setText("0");
        textField2.setText("0");
        setSize(230,150);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    class Enter implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String rz="";
            try{
                value1= Integer.parseInt(textField1.getText());
                value2= Integer.parseInt(textField2.getText());
                rz=value1+value2+"";
            }
            catch(NumberFormatException ex){
                rz="integers in each box please!";
            }
            finally{
                rez.setText(rz);
            }
        }
    }
    public static void main(String arg[]){
        new SumEx();
    }
}

 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

import java.util.*;
class NoNote extends Exception{
    String message;
    NoNote(String message){
        this.message = message;
        System.out.println(message);
    }
}
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;
        do{
            ok = true;
            System.out.print("next note:");
            note = sc.nextInt();
            try{
                if((note>6)||(note <2)){
                    throw new NoNote("outside [2,6]");
                }
            }
            catch(NoNote ex){
                ok = false;
            }
        }while(!ok);
        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;
}