Вы находитесь на странице: 1из 57

Cours Programmation Oriente Objet Gestion des Exceptions

Dr. Lassaad BAATI

Dr. Lassaad BAATI

Problmes des erreurs dans les programmes


erreur matrielle (imprimante dbranche, serveur en panne), contrainte physique (disque plein), erreurs de programmation (cas non prvu par le programme, division par zro, ouverture dun fichier qui nexiste pas), utilisateur rcalcitrant (type de donnes rentres par lutilisateur incorrect)

En cas de problmes
envoyer un message derreur, sauvegarder lensemble du travail en cours, permettre une sortie correcte du programme, revenir en arrire et effectuer un autre traitement.

Comment faire
Solution : tout prvoir (tester lgalit zro du dnominateur avant une division, etc.) Problme : vous avez beau tre un bon programmeur vous ne pouvez pas tout contrler
que faire dans le cas dun mauvais type en entre, ou pour les cas non prvus par le programme ?

Introduction
Cest un vnement qui se dclenche pendant lexcution dun programme et qui perturbe le flux normal de lensemble des instructions. En Java, une exception est une instance de la classe Exception ou dune de ses sous-classes.

ISIGK

. Dr. Lassaad BAATI

Dclenchement des exceptions


1. Erreur interne de Java 2. Erreur de programmation ou de droulement
Dpassement de borne, erreur dE/S, erreur rseau ...

3. Appel dune mthode qui lve une exception 4. Lancement volontaire dune exception avec throw
ISIGK . Dr. Lassaad BAATI 6

Exception
Le mcanisme de gestion derreur le plus rpandu est celui des exceptions. Quand une erreur se dclenche dans une mthode, celle-ci cre un objet (exception object).
Cet objet contient les informations sur lerreur (type derreur, tat du programme cet instant, etc).

La cration dun objet exception et le fournir au runtime est appele throwing an exception .
ISIGK . Dr. Lassaad BAATI 7

Les exceptions
Constat :

mme si programme au point $ toujours des bugs !! grer tous les cas possibles peut alourdir la programmation

introduction des exceptions


1. Dissocier la dtection d'une anomalie de son traitement. 2. Sparer la gestion des anomalies du reste du code lisibilit des programmes meilleure

Dfinition
Dfinition : Le principe de l'exception est de capturer une erreur lorsqu'on suppose qu'elle peut intervenir dans une partie de code.

try { r= numrateur / dnominateur; } catch (Exception e) { //traitement de l'exception System.out.println("Exception: " + e); }

Dclenchement explicite
Il est possible de dclencher explicitement une exception (on dira qu'on lve une exception) dans un bloc catch.
try { if (denominateur==0) throw new Exception(); } catch (Exception e) { //traitement de l'exception System.out.println("Exception: " + e); throw e; }

Il est possible de dclencher explicitement une exception en dehors d'un bloc catch, il faut alors le dclarer au niveau de la signature de la mthode qui peut lever cette exception.

Exemple
Exemple Dfinition d'une classe permettant de calculer la racine carre d'un nb (dans ) nb 0 class sqrt { private r ; public sqrt (int x) throws ErrNeg { if (x<0) throw new ErrNeg() ; this.r = racinecarre(x); } }

Mthode susceptible d'envoyer une exception

public void affiche() { system.out.println("resultat="+r); }

lever une exception

class ErrNeg extends Exception {...}

Les exceptions
Passage de paramtres au gestionnaire d'exception : ... if (x<0) throw new ErrNeg(x) ; ... class ErrNeg extends Exception { ErrNeg(int a) {x =a ;} public int x ; } Poursuite de l'excution instruction System.exit() n'est pas obligatoire l'excution peut se poursuivre avec les instructions suivant le bloc try

Lexiques: Acteurs et Actions


Operation Une mthode qui peut lever une exception. Invoker (appel) une mthode qui appelle des oprations et attrape les exceptions rsultantes. Exception Une description complte et concise dun vnement anormal. Raise (lever une exception) ramne une exception de lopration linvoker, appel throw en Java. Un
autre mot trs utilis est emit.

Handle (capturer) la rponse de invoker lexception, appel catch en Java. Backtrack (retour diffrent de undo) Abilit dfiler la pile des frames partir do les exceptions ont t tendues, jusqu la 1ere position seine de la pile.
ISIGK . Dr. Lassaad BAATI 13

Lexique: Types dExceptions


Matriel / Hardware
gnre par le CPU en rponse une erreur (division par zro, dpassement/dbordement, erreur de segmentation, etc).

Programmes / Software
dfinie par le dveloppeur pour reprsenter un nouveau type derreur. Ces exceptions portent souvent sur la smantique.

Erreur de domaine / Domain Failure


Les entres, ou les paramtres des oprations sont invalides ou inappropris.

Erreur de porte/ Range Failure


Lopration ne peut pas continuer son excution, ou sortie incorrecte.

Suivi / Monitor
Dcrit le statut dune opration en excution, cest un mcanisme pour la mise jour dexcution qui est plus simple que les subthreads.
ISIGK . Dr. Lassaad BAATI 14

Gestion traditionnelle des erreurs


Renvoi dune valeur de retour par la fonction
Authentique tat derreur: boolen
Retourne true / false

Retour par entier, cas particulier dun retour


Classiquement -1

Autres mcanismes
Renvoi dans les arguments

ISIGK

. Dr. Lassaad BAATI

15

Dfaillances approche traditionnelle


Le dveloppeur doit penser vrifier ses codes de retour Tout sauf cohrent
Diffrent selon les bibliothques, les appels

Lisibilit du code
Mlange traitement de donne/cas derreur

Erreur possiblement ignore par le dveloppeur surcharge du code destin au traitement normal cause des instructions traitant les exceptions qui lui sont entrelaces. Le but des mcanismes de traitement dexception intgres aux langages (Java, C++) est de
sparer clairement lcriture du code la partie traitement normal de la partie traitement des exceptions et de forcer le programmeur grer les exceptions gnres par les 16 mthodes quil utilise.ISIGK . Dr. Lassaad BAATI

Gestion des exceptions


La gestion des exceptions constitue une manire propre de grer les situations anormales.
Exception : Erreur soft quon peut capturer Error : erreur srieuse fin

Lide est de signaler les exceptions pour le processus courant en excution


Une exception est lance, ensuite capture. Une exception survient au moment de lexcution

Les exceptions peuvent oprer de faon asynchrone dans une methode 2 sous classes qui tendent throwable :
Exception, Error

Un-handled Exception Error (erreur fatale) RuntimeException


ISIGK . Dr. Lassaad BAATI 17

Lexique
throws Permet d'indiquer que la mthode est suceptible de lever une exception throw Lever une exception au premier handler disponible dans la pile dappel. try marque le dbut du bloc contenant lensemble des exception
handlers.

catch si le bloc try gnre une exception de ce type, on bascule vers ce bloc, pour excuter les traitements adquats. finally appel quand le bloc try conclut, et aprs la fin du bloc catch.
ISIGK . Dr. Lassaad BAATI 18

Exceptions
2 familles dexceptions:
non fatales fatales (provoquent larrt du programme).

Hirarchie des exceptions Java


java.lang
Object

Throwable

Error

Exception

ThreadDeath

RuntimeException

IOException

NullPointerException

IllegalArgumentException

java.io.FileNotFoundException

ISIGK

. Dr. Lassaad BAATI

20

Une exception est un objet de type Exception


Instancier par nimporte quelle sous-classe dException

Hirarchie RuntimeException et Error


Une hirarchie dexceptions non contrles par le compilateur

Hirarchie error: erreurs graves


Exemples
NoSuchMethodError: la mthode rfrence nest pas accessible StackOverflowError: dbordement de pile

Hirarchie RuntimeException
Exemples
ArithmeticException: une erreur arithmtique (division par 0) IndexOutofBoundsException: indice dun tableau est en dehors des bornes autorises.

Il nest pas obligatoire de grer les exceptions de type RuntimeException


public class ZeroDivide { static public void main(String[] args) { int a = 3; int b = 0; System.out.println("Resultat de la division : " + a/b); } } Ce code se compile mais une exception apparat au niveau de lexcution et le programme sarrte.
Une ArithmeticException est une RuntimeException.

Les RuntimeException ne sont pas vrifies par le compilateur

Les autres exceptions doivent tre prise en compte


public class TaperTouche { static public void main(String[] args) { System.out.println("Tapez une touche pour terminer le programme"); System.in.read(); } } Ce code ne compile pas parce que la mthode read() est susceptible de lever une exception de type IOException

Lappel dune mthode qui lance une exception (une mthode qui dclare quelle lance une exception) doit tre pris en compte dans le code appelant
Encapsuler lappel dans un bloc try/catch

Contrle de flot dans les blocs Try/catch


Try {
leve dexception

Instruction 1; // dans cette instruction il y a une possibilit Instruction i


1

Si le bloc Try russit


de

} catch (Exception ex) {


Instruction j; } Instruction k;
2

Contrle de flot dans les bloc Try/catch


Try {
leve dexception 1 Instruction i

Instruction 1; // dans cette instruction il y a une possibilit

Si le bloc Try choue


de

} catch (Exception ex) {


Instruction j; 2 } Instruction k;
3

Finally pour ce qui sexcute dans tous les cas


Try {
Instruction 1; Instruction i;

Try {
Instruction 1; Instruction i; Instruction k;

} catch (Exception ex) {


Instruction j; } finally { Instruction k; }

} catch (Exception ex) {


Instruction j; Instruction k; }

Remarque: si le bloc try/catch a une instruction return finally sexcute quand mme Le flot saute finally puis revient return

Extrait de la documentation de la classe read


Method Detail read public abstract int read() throws IOException
Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. A subclass must provide an implementation of this method. Returns:
the next byte of data, or -1 if the end of the stream is reached.

Throws:
IOException - if an I/O error occurs.

Deux manires de grer les exceptions: la prendre en compte ou lesquiver


import java.io.IOException; public class TaperTouche { static public void main(String[] args) { System.out.println("Tapez une touche pour terminer le programme"); try { System.in.read(); } catch(IOException e) { System.out.println("Une IOException a t dtecte !"); } } }

Lesquiver
Il sagit de dclarer que vous lancez lexception mme si techniquement ce nest pas vous qui la lancez public class TaperTouche { static public void main(String[] args) throws IOException { System.out.println("Tapez une touche pour terminer le programme"); System.in.read(); } }

public class TaperTouche { static public void LireClavier throws IOException { System.out.println("Tapez une touche pour terminer le programme"); System.in.read(); } } Public class Main { static public void main(String[] args) throws IOException { TaperTouche.LireClavier(); }

Si Main nesquive pas lexception ou ne lencapsule pas dans un bloc try/catch il y a une erreur de compilation.

Une RunTime exception peut tre galement intercept et dclar


public class ZeroDivide { static public void main(String[] args) { int a = 3; int b = 0; try {System.out.println("Resultat de la division : " + a/b); System.out.println("Instructions suivant la division..."); } catch(ArithmeticException e) {System.out.println("Une exception sest produite ! (ArithmeticException)"); } System.out.println("Instructions qui suivent le bloc catch..."); } } Maintenant, la division par zro ne provoque pas la fin du programme.

Crer ses propres classes dexception


Imposer la classe de driver de la classe standard Exception
Exemple transmission dun message au gestionnaire dexception sous forme dune information de type chane.
La classe Exception dispose dun constructeur un argument de type String dont on peut rcuprer la valeur laide de la mthode getMessage.

class MonZeroException extends Exception { public MonZeroException(String e){ super(e);} } public class laClauseThrows { public static void main (String[] args) { try{System.out.println("je verifie le nombre donne en argument."); LaClauseThrows.test(args); } catch (MonZeroException e){ System.out.println(e.getMessage()); // getMessage mthode de la classe Throwable // e.printStackTrace(); mthode de la classe Throwable affiche ltat de la pile dappels } } public static void test(String [] args) throws MonZeroException{ int n=Integer.parseInt(args[0]); if (n==0) throw new MonZeroException("jai vu un zero"); System.out.println("il ny a pas eu dexception pour zero"); } } }

Exemple transmission dinformation au constructeur de lobjet exception


class Point { private int x,y; public Point(int x, int y) throws ErrConst { if ((x<0) || (y<0)) throw new ErrConst(x,y); this.x =x; this.y=y; } public void affiche() { System.out.println("Coordonnes:" +x+" "+y); } } class ErrConst extends Exception { public int abs; public int ord; ErrConst (int abs, int ord) { this.abs = abs; this.ord=ord; } } public class Exoinfo1 { public static void main (String args[]) { try {Point a = new Point (1,4); a.affiche(); a = new Point (-3,5); a.affiche(); } catch (ErrConst e) {System.out.println("Erreur construction point"); System.out.println("coordonnees souhaites"+e.abs+" "+e.ord); System.exit(-1);} } }

public class TestExceptions { Exercice public static void main (String [] args) { String test = "non"; try { System.out.println("Dbut de try"); prendreRisque(test); System.out.println("Fin de try"); } catch (HorribleException he) { System.out.println("Horrible exception"); } finally { System.out.println("finally"); } System.out.println("fin de main"); } static void prendreRisque(String test) throws HorribleExeception { System.out.println("dbut de risque"); if ("oui".equals(test)) { throw new HorribleException(); } System.out.println("fin de risque"); return; } } Quel est le rsultat quand test vaut non et quand test vaut oui ?

Grer plusieurs types dexceptions


public class plusieursCatchs { public static void main (String[] args){ try{ System.out.println("je verifie le nombre donne en argument."); int n=Integer.parseInt(args[0]); if (n==0) throw new ZeroException(""); if (n>0) throw new SupAZeroException(""); if (n<0) throw new InfAZeroException(""); } catch (ZeroException e){ System.out.println("le nombre etait nul"); } catch (SupAZeroException e){ System.out.println("le nombre etait superieur a zero"); } catch (InfAZeroException e){ System.out.println("le nombre etait inferieur a zero"); } } }

Les blocs catch doivent tre ordonns du plus petit au plus grand
Cela dpend de la hirarchie dhritage

Syntaxe gnrale
public void setProperty(String p_strValue) throws NullPointerException { if (p_strValue == null) { throw new NullPointerException(...); } } //--------------------------------------------------public void myMethod() { MyClass oClass = new MyClass(); try { oClass.setProperty(foo); oClass.doSomeWork(); } catch (NullPointerException npe) { System.err.println(Unable to set property: +npe.toString()); } finally { oClass.cleanup(); } }
ISIGK . Dr. Lassaad BAATI 40

Lancer une exception


Linstruction throw exception, lance une exception
Ex: throw new UneException;

Lorsquune mthode est susceptible de lancer une exception ou de la propager, alors elle doit le specifier dans sa signature grce au mot-cl throws suivi de la liste des types dexception quelle lance ou propage.
float f(float x, y, z) throws ArithmeticException {
if( y + z == 0) throw new ArithmeticException(); return x / (y + z);

} Sortir du programme . Dr. Lassaad Si lexception nest pas leve BAATI

ISIGK

41

Lancer une Exception (suite)


Cas particulier : si lexception lance est une instance de RuntimeException ou de ses sous-classes, il nest pas ncessaire de le spcifier dans la signature de la mthode. Exemple :
int fonction(...) //throws RuntimeException { if(...) throw new RuntimeException(); return ...; }
ISIGK . Dr. Lassaad BAATI 42

Capturer une exception


Lorsquun bloc dinstructions contient linvocation dune mthode susceptible de retourner des exceptions, il faut lui associer les traitements particuliers requis pour chaque type dexception quil va capturer. Syntaxe :
try { ... // code gnrant des exceptions ventuelles } catch(UneException e1) //rattraper une { ... // code traitant les exceptions de type UneException } catch(UneAutreException e1) //rattraper une autre { ... // code traitant les exceptions de type UneAutreException } ... // autres blocsDr. Lassaad BAATI ISIGK . catch

43

Exemple: division par zero

ISIGK

. Dr. Lassaad BAATI

44

Exemple: division par zero


void calculerDiviser() { float x, y, z; ... // saisie des valeurs de x, y et z try { return x / (y + z); } catch(ArithmeticException e) { System.out.println("Erreur: division par zro"); e.printStackTrace(); } }
ISIGK . Dr. Lassaad BAATI 45

Relance dune exception


Si une mthode ne contient pas de bloc trycatch alors quelle invoque une mthode susceptible de lancer une exception (dont le type ne drive pas de RuntimeException) alors elle relance elle-mme automatiquement lexception au niveau de la mthode qui la invoque. Dans ce cas, il faut quelle explicite dans sa signature la liste des types des exceptions quelle ne rceptionne pas.
ISIGK . Dr. Lassaad BAATI 46

Propagation dune exception


//Fonction o lexception est gnre void calculerDivier() throws ArithmeticException { //propagation de lexception par throws float x, y, z; ... // saisie des valeurs de x, y et z { return x / (y + z); } // fonction appelante public float f(float x, y, z) throws ArithmeticException { try {calculerDiviser();} catch( ArithmeticException e) { System.out.println("Erreur: division par zro"); e.printStackTrace(); } ISIGK . Dr. Lassaad BAATI 47 }

Propagation dune exception


throws, dcaler/propager une exception :
[<modificateur>] <type> <nomMthode> ([<paramtres>]) throws <liste d'exceptions> { <corps de la mthode pouvant lever des exceptions > }

Les exceptions listes sont propages/transmises la mthode appelante si elles sont leves dans le corps de la mthode traite. Une exception peut tre propage jusqu' une mthode appelante qui la capture et la traite. Elle permet d'indiquer que la mthode est suceptible de lever une exception qu'elle ne capture pas par un try-catch ArithmeticException sera propage/transmise la mthode appelante si elle est leve. Donc il faut que les mthodes qui appelle la mthode solution
mettent ventuellement en place une mcanisme de capture try-catch ou qu'elles propagent elles aussi l'exception.
ISIGK . Dr. Lassaad BAATI 48

finally
Si une exception est lance dans un bloc try, ce sont ses blocs catch associs qui essaient dabord de la rceptionner. On peut rajouter un bloc finally { ... } aprs les blocs catch. Ce qui est dans le bloc finally sera excut quoi quil arrive :
soit aprs lexcution normale du bloc try, soit aprs lexcution dun bloc catch, soit juste avant que lon quitte la mthode cause dune exception lance mais non traite dans la mthode.

ISIGK

. Dr. Lassaad BAATI

49

Classement des exceptions


Les exceptions en JAVA peuvent tre classes en :
Error
Erreurs critiques non grables

Exception
Erreurs grables (IOException, etc.)

RuntimeException
Erreurs ventuellement grables
(NullPointerException)

Les exceptions quon cre tendent lune des exceptions de ces groupes
ISIGK . Dr. Lassaad BAATI 50

Exceptions prdfinies
Il existe dj une hirarchie de classes hritant de la classe Exception. Cette classe (et donc toutes ses drives) contient deux constructeurs :
un constructeur sans paramtre et un constructeur prenant une chane en paramtre qui reprsente le texte explicitant lerreur.

Parmi les mthodes dclares, il y a notamment les mthodes (throwable)


String getMessage() qui retourne le message derreur pass au constructeur et void printStackTrace() qui affiche le contenu de la pile dexcution.
ISIGK . Dr. Lassaad BAATI 51

La hirarchie RuntimeException
La classe RuntimeException hrite dException. Les classes suivantes hritent de RuntimeException :
ArithmeticException : erreur dans un calcul arithmtique, division par zro, ... IndexOutOfBoundsException : indice en dehors des limites dans un tableau) NullPointerException : appel dune mthode sur une variable ne rfrenant aucun objet ISIGK . Dr. Lassaad BAATI 52 ...

La hirarchie IOException
La classe IOException hrite aussi dException. Elle regroupe les exceptions rapportes aux traitements dentres-sorties. Ses sous-classes sont :
EOFException, FileNotFoundException, InterruptedIOException, MalformedURLException, ObjectStreamException, ...
ISIGK . Dr. Lassaad BAATI 53

Utilisation des exceptions


Ne pas abuser des exceptions Ne pas rceptionner une exception pour sen dbarrasser.
Si on ne sait pas traiter une exception et quon pense quelle ne pourra pas tre traite un niveau suprieur, crire ceci :
catch(Exception e) { throw new RuntimeException(e); }.

Traiter lexception au niveau qui convient le mieux. Quand cest possible, rparer le problme correspondant lexception et rappeler la mthode o elle a eu lieu. (sinon arrter
le pgm)

Il existe des cas o lexception est partiellement traitable au niveau courant et partiellement des niveaux suprieurs.
Effectuer le traitement au niveau courant, puis relancer lexception (ou un autre type dexception) un niveau suprieur.
ISIGK . Dr. Lassaad BAATI 54

Exemple
public void foo() { try { /* marque le dbut du bloc try-catch */ int a[] = new int[2]; a[4] = 1; /* dclenche une exception dpassement de lindex */ } catch (ArrayIndexOutOfBoundsException e) { System.out.println("exception: " + e.getMessage()); e.printStackTrace(); } } /* Ce code peut etre compil mais gnre une exception en excution et dclenche larrt du programme */ public int[] bar() { int a[] = new int[2]; for (int x = 0; x <= 2; x++) { a[x] = 0; } return a; ISIGK . Dr. Lassaad BAATI }

55

tapes : trycatchfinally
Chaque bloc try doit avoir au moins un bloc catch ou un bloc finally attach. Si une exception est leve durant le bloc try :
Le reste du bloc try est ignor. Sil y a un bloc catch qui correspond lexception leve, il sera excut. Sil y a un bloc fnally, il sera aussi excut.

Sil ny a pas dexceptions leves, et il ny a pas dinstruction System.exit() :


Le JVM passe au bloc finally.
ISIGK . Dr. Lassaad BAATI 56

Conclusion
La gestion des exceptions permet de dissocier le programme principal de la gestion des erreurs, ou des arrts brusques du programme. Ce nest pas une nouvelle structure de contrle en plus des if, while, for, switch. La gestion des erreurs ralentit considrablement la vitesse du programme Les exceptions doivent rester exceptionnelles!