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:
|
|
Erreur pendant l'exécution du programme |
|
Causer une exception (jeter une exception) |
|
Rattraper une exception et aller a une autre partie du programme afin de résoudre le problème |
|
La partie du programme qui fait ca |
|
La séquence des ``call statement`` qui finit par méthode dans laquelle a eu lieu l’exception |
|
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 :
![]() |
![]() |
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, male loup, avoir faim:true animaux: animal: jeune, male,herbivore, rapide: true animal: adulte, male loup, avoir faim:true animaux: animal: jeune, male,herbivore, rapide: true animal: adulte, male loup, avoir faim:true |
Un exemple pour illustrer "finally clause"
class MonException extends Exception {}
public class FinallyClause { |
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 { public void init(){ public void paint(Graphics g){ g.drawString("Type
a number
in each box.", 40, 50); class Enter implements ActionListener
{ } |
L'addition des deux entiers - Exception saisie
import java.awt.*; import java.applet.*; import java.awt.event.*; public class AppletException extends Applet { public void init(){ public void paint(Graphics g){ g.drawString("Type
a number
in each box.", 40, 50); g.drawString(s, 80,
100); class Enter implements ActionListener
{ } |
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; } } |