page précédantetable des matièrespage suivante

Exceptions

Introduction

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.

Un exemple
  

class Bull extends Exception {
    public String s;
    Bull(String par) {
        s = par;
    }
}
enum Age {
    YOUNG, ADULT
}
enum Sex {
    MALE, FEMALE
}
enum Run {
    FAST, SLOW
}

class Animal {
    private Age age;
    private Sex sex;
    Animal(Age age, Sex sex) {
        this.age = age;
        this.sex = sex;
    }
    public Age age() {
        return age;
    }
    public Sex sex() {
        return sex;
    }
    public String toString() {
        return " animal: " + age + ", " + sex;
    }
}

class Herbivore extends Animal {
    public Run run;
    Herbivore(Age age, Sex sex, Run run) {
        super(age, sex);
        this.run = run;
    }
    public String toString() {
        return super.toString() + ",herbivore:" + run;
    }
}

class Carnivore extends Animal {
    private boolean starving;
    Carnivore(Age age, Sex sex) {
        super(age, sex);
        starving = true;
    }
    public Herbivore[] tear(Herbivore[] herd) throws Bull,
    ArrayIndexOutOfBoundsException {
        if (starving) {
            if (herd[herd.length - 1].age() == Age.ADULT &&
            herd[herd.length - 1].sex() == Sex.MALE)
                throw new Bull("BULL FOUND!!");
            Herbivore[] buffer = new Herbivore[herd.length - 1];
            System.arraycopy(herd, 0, buffer, 0, herd.length - 1);
            starving = false;
            return buffer;
        }
        return herd;
    }
    public void sleep() {
        starving = true;
    }
    public String toString() {
        return super.toString() + " wolf , starving:" + starving;
    }
}

public class MyException {
    public static void prt(Animal[] animal, Animal wolf) {
        System.out.println("\n\n\n animals: \n");
        for (int i = 0; i < animal.length; i++)
            System.out.println("" + animal[i]);
        System.out.println("\n" + wolf);
    }
    public static void main(String[] arg) {
        Herbivore[] cows = new Herbivore[(int) (Math.random() * 10)];
        for (int i = 0; i < cows.length; i++) {
            cows[i] = new Herbivore(
                    Math.random() > 0.5 ? Age.YOUNG : Age.ADULT,
                    Math.random() > 0.5 ? Sex.MALE : Sex.FEMALE,
                    Math.random() > 0.5 ? Run.FAST : Run.SLOW);
        }
        Carnivore wolf = new Carnivore(Age.ADULT, Sex.MALE);
        prt(cows, wolf);
        for (;;) {
            try {
                cows = wolf.tear(cows);
            }
            catch (Bull e) {
                System.out.println(e.s);
                System.out.println("\nEnd of the program");
                System.exit(1);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("NO MORE COWS!");
                System.out.println("\nEnd of the program");
                System.exit(1);
            }
            wolf.sleep();
            prt(cows, wolf);
        }
    }
}
 animals:

 animal: YOUNG, MALE,herbivore:FAST
 animal: YOUNG, FEMALE,herbivore:SLOW
 animal: YOUNG, MALE,herbivore:FAST
 animal: YOUNG, MALE,herbivore:SLOW
 animal: ADULT, MALE,herbivore:FAST
 animal: ADULT, MALE,herbivore:FAST
 animal: ADULT, MALE,herbivore:FAST
 animal: ADULT, FEMALE,herbivore:SLOW

 animal: ADULT, MALE wolf , starving:true



 animals:

 animal: YOUNG, MALE,herbivore:FAST
 animal: YOUNG, FEMALE,herbivore:SLOW
 animal: YOUNG, MALE,herbivore:FAST
 animal: YOUNG, MALE,herbivore:SLOW
 animal: ADULT, MALE,herbivore:FAST
 animal: ADULT, MALE,herbivore:FAST
 animal: ADULT, MALE,herbivore:FAST

 animal: ADULT, MALE wolf , starving:true
BULL FOUND!!

End of the program

_____________________________

   animals:

 animal: ADULT, FEMALE,herbivore:SLOW

 animal: ADULT, MALE wolf , starving:true



 animals:


 animal: ADULT, MALE wolf , starving:true
NO MORE COWS!

End of the program

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"

 

Exemple2: 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();
           }
    }

}


 
   

- 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