Programmation java Gestion des erreurs d'exécution Daniel Tschirhart : Programmation Java V1.34 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Gérer les erreurs d’exécution n Il est difficile, voir impossible au concepteur d’une classe, de prévoir le mode de récupération d’erreur le mieux adapté. n C’est à l’application de prévoir le mode de réaction le plus approprié : n n il faut que la conception de la classe incriminée laisse la possibilité de définir un mode de récupération. Face à l’impossibilité à un programme de continuer, le concepteur d’une classe peut définir les politiques suivantes : n n n n n utiliser la politique de l’autruche ! terminer le programme (attention aux pertes des données !), arrêter le traitement en cours et retourner une erreur dans une variable globale (mais il faut penser à la tester !) appeler une fonction de gestion d’erreur qui doit toutefois se terminer avec l’une des possibilités précédentes, utiliser le mécanisme de gestion des exceptions. 2 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Utiliser la politique de l’autruche double div(double a, double b) { return a/b; } Et si b = 0 ! 3 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Terminer le programme en cas d’erreur double div(double a, double b) { if (b==0) System.exit(1); return a/b; } 4 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Arrêter le traitement en cours et retourner un code d’erreur dans un attribut double div(double a, double b) { if (b==0) { errorNo=1; Met à jour une variable et arrête le programme return 0; } return a/b; } 5 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Gestion des erreurs à base d’exceptions n n n Quand l'exécution d'une application ne se déroule pas normalement, l'interpréteur java répond en levant une exception. Exemple si une application essaie d'ouvrir un fichier inexistant, une exception est levée. Lorsque une exception se produit, le programme Java crée un objet pour représenter cette exception. Java utilise une forme de gestion des exceptions structurées autour des blocs try/catch/finally. n n n n n n try capture l'exception, catch traite celle-ci, finaly (facultatif) est le passage obligé qu'il y ai eut exception ou non. Si une exception n'est pas interceptée par l'application, celle–ci est arrêtée. On peut créer ses propres classes d'exceptions en dérivant ses classes à partir de la classe Exception. Les exceptions sont hiérarchisées, la dernière exception à traiter dans le bloc catch est l’exception de la classe Exception. 6 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Mots clés utilisé pour gérer les exceptions 7 Mise en place d’un mécanisme de gestion d’erreurs à base d’exceptions Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 1. Définir une classe dérivant de la classe Exception (par exemple ExceptionDivZero) 2. Lorsqu’une erreur se produit, lancer l’exception à l’aide du mot throw en instanciant un objet de la classe précédente. 3. Intercepter l’exception en encadrant l’appel de la fonction lançant des exceptions par le bloc try..catch 8 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 1. Définir un classe de type Exception public class ExceptionDivZero extends Exception { Hérite de la classe Exception // peut être vide } 9 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 2. Lancer une exception double div(double a, double b) throws ExceptionDivZero { indique que la fonction lance l’exception ExceptionDivZero if (b==0) throw new ExceptionDivZero(); return a/b; } lance une exception en instanciant un objet de la classe ExceptionDivZero 10 3. Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Intercepter l’exception en encadrant l’appel de la fonction lançant des exceptions par le bloc try..catch class Exemple { double div(double a, double b) capture l'exception throws ExceptionDivZero { … } traite l'exception public static void main(String[] args) { Exemple ex = new Exemple(); try { System.out.println(ex.div(3,0)); } catch (ExceptionDivZero e) { System.out.prinln("Division par zéro"); } } 11 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Passage de paramètre au gestionnaire d'exception n n Il est possible de passer un paramètre de type String au gestionnaire d'exception en définissant un constructeur spécifique dans sa classe d'exception. Ce constructeur reçoit un paramètre de type String qui peut être utilisé pour fournir davantage de renseignements sur l'erreur. 12 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Passage de paramètres au gestionnaire d'exception (2) public class ExceptionDivZero extends Exception constructeur par défaut { public ExceptionDivZero() { } public ExceptionDivZero(String param) { super(param); } } passe le paramètre au gestionnaire d'exception constructeur spécifique 13 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Utilisation du paramètre passé class Exemple { double div(double a, double b) throws ExceptionDivZero { if (b==0) throw new ExceptionDivZero("Fonction div"); return a/b; } public static void main(String[] args) { Exemple ex = new Exemple(); try { System.ou.println(ex.div(3,0)); } catch (ExceptionDivZero e) { System.out.prinln(e); // affiche: ExceptionDivZero Fonction div } } 14 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Classes d'exceptions prédefinies les plus courantes n Exception n IoException n n n n n n ArgumentNullException ArrayStoreException IllegalArgumentException IndexOutOfBoundsException NullPointerException RuntimeException n n FileNotFound EndOfFileException 15 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 important Esquiver des exceptions Exemple : une fonction pop() lève une exception ExceptionPileVide. Pour reporter la capture des exceptions à la fonction appelante il faut déclarer les exceptions à intercepter avec une clause throws. n public void plus() throws NumberFormatException, ExceptionPileVide { Complex d = operand.pop(); plus() n'intercepte pas les exceptions Complex g = operand.pop(); spécifiées par throws operand.push(Complex.Add(g, d)); } public void run() { try { c'est la fonction appelante qui les interceptes //... plus(); } catch (Exception e) { System.out.println(e); } } 16 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Exercices La classe Test, placée dans le même répertoire que la classe Etudiant contient la définition suivante : class Test { public static void main(String[] args) { Etudiant e1 = new Etudiant(); Etudiant e2 = new Etudiant("Dupond", 2012,"Insa Lyon"); Etudiant e3 = new Etudiant("Lajoie", 2012, "Eigi "); System.out.println(e3); } } n Quel est le nom du fichier source contenant la classe Test ? n Quel est le constructeur appelé par la ligne ci-dessous, comment s'appelle ce constructeur Etudiant e1 = new Etudiant(); n Quel est le constructeur appelé par la ligne ci-dessous, comment s'appelle ce constructeur Etudiant e2 = new Etudiant("Dupond", 2012, "Insa Lyon"); n 17 Daniel Tschirhart : Gestion des erreurs d'exécution V1.0 Exercices n La classe Test, placée dans le même répertoire que la classe Etudiant contient la définition suivante : class Test { public static void main(String[] args) { Etudiant e1 = new Etudiant(); Etudiant e2 = new Etudiant("Dupond", 2012,"Insa Lyon"); Etudiant e3 = new Etudiant("Lajoie", 2012, "Eigi "); System.out.println(e3); } } n n n Après instanciation des objets e1, e2, e3, que contiennent les attributs de chaque objet. La ligne ci-dessous provoque une erreur de compilation. Pourquoi ? Etudiant e4 = new Etudiant("Dupond", 2012); Quel est le fichier obligatoirement présent dans le répertoire comportant le fichier Test.class pour que l'exécution réussisse ? 18