page précédantetable des matièrespage suivante

Exceptions

On peut découvrir les erreurs dans un programme pendant:
        La compilation
        L'exécution

Langages comme C traitent les erreurs en utilisant des mots de statut - il faut les vérifier pendant l'exécution du programme.

Deux risques dans cette approche:
        - de ne pas vérifier tous les fautes possibles (ça ne peut arriver que à d'autres)
        - de convertir le programme dans un  cauchemar illisible des vérifications

Dans la POO on a choisi une autre approche – les exceptions. Les exceptions changent la séquence d'exécution, quand il arrive un événement important ou inattendu, habituellement une erreur. Elles donnent le contrôle à des autres parties du programme qui font l’effort de réagir convenable a ces erreurs.

Les atouts de cette approche :
     - On n’a plus besoin de vérifier tous les points cruciaux. Tous ce qu’on doit faire c’est de gérer le problème à une place spéciale nommée « exception handler ». Comme ça on peut séparer le code de ce qu’on veut faire du code du problème et faire le programme plus lisible.
    - On n’est pas obligé de savoir comment gérer le problème sur place. Dans ce cas on peut « jeter (throw) une exception » et laisser la décision quoi faire à un autre contexte du programme.

Quelques notions:
 
Action
Notion
Erreur pendant l'exécution du programme
Exception
Causer une exception (jeter une exception)
Throwing
Rattraper une exception et aller a une autre partie du programme afin de résoudre le problème
Catching
La partie du programme qui fait ca
Catchblock
La séquence des ``call statement`` qui finit par méthode dans laquelle a eu lieu l’exception 
Stack trace

Quelques exceptions prédéfinies:

Exception

    ClassNotFoundException

    IllegalAccessException

    InterrupredException

    NoSuchMethodException

    RuntimeException

        ArithmeticException

        ArrayStoreException

        ClassCastException

        NegativeArraysizeException

        NullPointerException

        SecurityException

        IndexOutOfBoundsException

        String IndexOutOfBoundsException

        Array IndexOutOfBoundsException

        IllegalArgumentException

        NumberFormatException

        IllegalThreadStateException
 

Throwing
Supposons que l'objet 'q' n'est pas encore initié. On peut verifié ça avant d'utliser l'objet et laisser traitement de la situation dans un autre contexte:

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

Comme ça on peut ne pas s'occuper  traitement de la situation.

On peut jeter une exception avec un argument (chaîne des caractères):

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

Tous les exceptions ont deux constructeurs – le premier c’est le constructeur par défaut (sans arguments) et le deuxième c’est avec un argument – chaîne des caractères qui peut être analyser dans l’ »exception handler »

Si une exception est jetée dans une méthode, il se produit la procedure suivante :




Ça ressemble un peut de "return" normal de la méthode mais on peut aller beucoup plus haut dans le contexte de traitement du programme - ou l'exception correspondant est traité.
 
 

Catching

On peut introduire dans le programme des blocs surveillés:

try {
        //code surveillé qui peut générer des exceptions
}

catch(type1 id1) { // on peut avoir zero 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
}

S'il n'existe pas de bloc try/catch ou bien il existe mais n'existe pas d'instruction catch qui corresponde à l'exception levée, l'exception est envoyée à la méthode appelante et ainsi de suite jusqu'à ce qu'elle sera capturée.

Les traitement blocs("catch blocs") doivent apparaître immédiatement après le « try » bloc

Terminaison ou bien prolongation

Il y a deux approches dans la théorie des exception. Le premier (adopté en Java) accepte que les erreurs sont graves et qu’on doit terminer l’exécution du programme. Donc jeter une exception habituellement a pour résultat terminaison de l’exécution de la méthode concernée.

Le deuxième accepte qu’après le traitement de l’exception on peut continuer le programme("resumption"). Pour réaliser le deuxième approche en Java il faut prendre des précautions spéciales (introduire « try-catch » bloc à la place de l’erreur et s’il faut mettre tous ça dans « while » clause).

Création des exceptions propres
On n'est pas obligé de se limiter avec les exceptions existantes. Les exceptions créées doivent étendre l'exception le plus proche possible. Si on ne peut trouver une exception convenable on étends la classe Exception.

Une exemple
 
class Taureau extends Exception{
   public String s;
  Taureau(String par){ s = par; }
}
class Age{
   public static final int JEUNE=0;
   public static final int ADULTE=1;
   public static final int DOYEN=2;
}
class Sexe{
   public static final boolean MALE=true;
   public static final boolean FEMELLE = false;
}
class Animal {
   private int age;
   private boolean sexe;
   Animal(int age, boolean sexe){
     this.age = age;
     this.sexe = sexe;
  }
   public int age(){ return age; }
   public boolean sexe(){return sexe;}
   public String toString(){
      String age_s="jeune";
      switch (age){
         case 1: age_s = "adulte"; break;
         case 2: age_s = "doyen";
      }
       return " animal: " + age_s +", "+ (sexe?"male":"femelle");
   }
}
class Herbivore extends Animal{
   public boolean rapide;
   Herbivore(int age, boolean sexe, boolean rapide){
         super(age,sexe);
         this.rapide = rapide;
   }
   public String toString(){
       return super.toString() + ",herbivore, rapide: " +rapide;
   }
}
class Carnivore extends Animal{
   private boolean avoirFaim;
   Carnivore(int age, boolean sexe){
      super(age,sexe);
      avoirFaim = true;
   }
   public Herbivore[] devorer(Herbivore[] troupeau) throws Taureau{
      if (avoirFaim){
          if(troupeau.length == 0) throw new Taureau("rien a manger");
          if(troupeau[troupeau.length-1].age() == Age.ADULTE &&
              troupeau[troupeau.length-1].sexe() == Sexe.MALE) 
                 throw new Taureau("taureau");
           Herbivore[] tampon = new Herbivore[troupeau.length-1];
           System.arraycopy(troupeau,0,tampon,0,troupeau.length-1);
           avoirFaim = false;
           return tampon;
      }
      return troupeau;
  }
   public void dormir() {avoirFaim = true;}
   public String toString(){
        return super.toString() + " loup, avoir faim:" +avoirFaim;
   }
}
public class MonException {
   public static void prt(Animal[] animal, Animal loup){
       System.out.println("\n\n\n animaux: \n");
       for(int i = 0; i < animal.length; i++)
            System.out.println(""+animal[i]);
       System.out.println("\n"+loup);
   }
    public static void main(String[] arg){
        Herbivore[] vaches=new Herbivore[10];
        for(int i = 0; i < vaches.length; i++)
        vaches[i] = new Herbivore((int)(Math.random()*3),
                             (int)(Math.random()*2)>0?true:false,
                             (int)(Math.random()*2)>0?true:false);
        Carnivore loup = new Carnivore(Age.ADULTE,Sexe.MALE);
        prt(vaches,loup);
        for(;;){
            try{
               vaches = loup.devorer(vaches);
           }
           catch (Taureau e) {
                 System.out.println(e.s);
                 System.exit(1);
           }
           loup.dormir();
           prt(vaches,loup);
       }
   }
}
 animaux: 

 animal: jeune, male,herbivore, rapide: true
 animal: adulte, femelle,herbivore, rapide: true
 animal: jeune, femelle,herbivore, rapide: true
 animal: doyen, femelle,herbivore, rapide: false
 animal: jeune, femelle,herbivore, rapide: true
 animal: doyen, male,herbivore, rapide: true
 animal: adulte, femelle,herbivore, rapide: true
 animal: adulte, male,herbivore, rapide: true
 animal: jeune, femelle,herbivore, rapide: true
 animal: adulte, femelle,herbivore, rapide: true

 animal: adulte, male loup, avoir faim:true
 
 

 animaux: 

 animal: jeune, male,herbivore, rapide: true
 animal: adulte, femelle,herbivore, rapide: true
 animal: jeune, femelle,herbivore, rapide: true
 animal: doyen, femelle,herbivore, rapide: false
 animal: jeune, femelle,herbivore, rapide: true
 animal: doyen, male,herbivore, rapide: true
 animal: adulte, femelle,herbivore, rapide: true
 animal: adulte, male,herbivore, rapide: true
 animal: jeune, femelle,herbivore, rapide: true

 animal: adulte, male loup, avoir faim:true
 
 

 animaux: 

 animal: jeune, male,herbivore, rapide: true
 animal: adulte, femelle,herbivore, rapide: true
 animal: jeune, femelle,herbivore, rapide: true
 animal: doyen, femelle,herbivore, rapide: false
 animal: jeune, femelle,herbivore, rapide: true
 animal: doyen, male,herbivore, rapide: true
 animal: adulte, femelle,herbivore, rapide: true
 animal: adulte, male,herbivore, rapide: true

 animal: adulte, male loup, avoir faim:true
taureau
 

Un exemple pour illustrer "finally clause"
 
 
class MonException extends Exception {}

public class FinallyClause {
  static int count = 0;
  public static void main(String[] args) {
    while(true) {
      try {
        // Post-increment ( zero la première fois):
        if(count++ == 0)
          throw new MonException();
        System.out.println("No exception");
      } catch(MonException e) {
        System.out.println("MonException");
      } finally {
        System.out.println("Dans /"finally clause/"");
        if(count == 2) break; // out of "while"
      }
    }
  }
 

MonException
Dans "finally clause"
No exception
Dans "finally clause"

 

Exemple: L'addition des deux entiers - Exception non prevue
 
 
 
 
import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class AppletSum extends Applet {
    TextField textField1;
    TextField textField2;

    public void init(){
        textField1 = new TextField(5);
        textField2 = new TextField(5);
        textField1.addActionListener(new Enter());
        textField2.addActionListener(new Enter());
        add(textField1);
        add(textField2);
        textField1.setText("0");
        textField2.setText("0");
    }

    public void paint(Graphics g){
        int value1;
        int value2;
        int sum;

        g.drawString("Type a number in each box.", 40, 50);
        g.drawString("The sum of the values is:", 40, 75);
        String s = textField1.getText();
        value1 = Integer.parseInt(s);
        s = textField2.getText();
        value2 = Integer.parseInt(s);
        sum = value1 + value2;
        s = String.valueOf(sum);
        g.drawString(s, 80, 100);
    }

    class Enter implements ActionListener { 
           public void actionPerformed(ActionEvent e) { 
              repaint();
           }
    }

}


 
 
 
 

L'addition des deux entiers - Exception saisie
 
 
 
 
import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class AppletException extends Applet {
    TextField textField1;
    TextField textField2;

    public void init(){
        textField1 = new TextField(5);
        textField2 = new TextField(5);
        textField1.addActionListener(new Enter());
        textField2.addActionListener(new Enter());
        add(textField1);
        add(textField2);
        textField1.setText("0");
        textField2.setText("0");
    }

    public void paint(Graphics g){
        int value1;
        int value2;
        int sum;
        String s;

        g.drawString("Type a number in each box.", 40, 50);
        g.drawString("The sum of the values is:", 40, 75);
        try {
            s = textField1.getText();
            value1 = Integer.parseInt(s); 
            s = textField2.getText(); 
            value2 = Integer.parseInt(s); 
            sum = value1 + value2;
            s = String.valueOf(sum); 
         }catch(NumberFormatException e){
            s = "Erreur - il faut introduire nombre !!!";
         }

        g.drawString(s, 80, 100);
    }

    class Enter implements ActionListener { 
           public void actionPerformed(ActionEvent e) { 
              repaint();
           }
    }

}

 

Exception  d'utilisateur - traité dans la fonction

class NoNote extends Exception{
    String message;
    NoNote(String message){
        this.message = message;
        System.out.println(message);
    }
}
import java.util.*;
public class Exc3 {
    static Scanner sc=new Scanner(System.in);
    public static void main(String arg[]){
        System.out.println("Note: "+Note());
    }
    static int Note(){
        boolean ok;
        int note=200;
        do{
            ok = true;
            System.out.print("next note:");
            try{
                String s= sc.nextLine();
                note = Integer.parseInt(s);
            }
            catch(NumberFormatException ie){
                System.out.println("Integer please!");
                ok=false;
                continue;
            }
            try{
                if((note>20)||(note <0)){
                    throw new NoNote("outside [0,20]");
                }
            }
            catch(NoNote ex){
                ok = false;
            }
        }while(!ok);
        return note;
    }
}

Exception  d'utilisateur - traité hors la fonction

class NoNote extends Exception{
    String message;
    NoNote(String message){
        this.message = message;
        System.out.println(message);
    }
}
import java.util.*;
public class Exc4 {
    static Scanner sc=new Scanner(System.in);
    public static void main(String arg[]){
        int note=0;       //initialization
        boolean ok;
        do{
            ok=true;
            try{
                note = Note();
            }       
            catch(NoNote ex){
                ok = false;
            }
            catch(NumberFormatException im){
                ok=false;
                System.out.println ("Integer please");
               
            }
        }while(!ok);
        System.out.println("Note: "+note);
    }

    static int Note() throws NoNote{
        int note;
        System.out.print("next note:");
        note = Integer.parseInt(sc.nextLine());
        
        if((note>20)||(note <0)){
            throw new NoNote("outside [0,20]");
        }
        return note;
    }
}

page précédantetable des matièrespage suivante