Exceptions IFT1025: Programmation 2 Jian-Yun Nie

Preview:

Citation preview

Exceptions

IFT1025: Programmation 2

Jian-Yun Nie

Concepts

• Erreur vs. Exception– Erreur: Un erreur logique impossible de réparer– Exception: un événement imprévu

• Laisser l’exception sans traiter (échec du programme)• Traiter l’exception (le programme continue après le traitement)

• Traitement d’exception– Un contrôle de sécurité

• Appel d’une méthode dans de bonnes conditions ?• Exécution de la méthode se déroule correctement ?• …• Sinon, quelles alternatives, correction ?

– Mécanisme de traitement: général (classe) pour faciliter les traitements

Échec d’un programme

• Impossibilité pour le système d’accomplir une tâche

• 2 raisons d’échec– Erreur logique dans l’implantation (la faute du

programmeur)– Impossibilité d’obtenir des ressources nécessaires

(e.g. fichier)

• Dans le cas d’erreur, pas réparable (seulement un message d’erreur)

• Mais pour la second classe: possible de traiter

Ressources nécessaires

• Matériel

• Système d’exploitation

• Fichiers

• Réseau

• Base de données

• Utilisateur (interaction)

Exception

• Apparition d’une situation anormale, détectable, qui conduit à l’échec du programme

• Possibilité pour un programme de détecter et traiter certaines exceptions pour éviter l’échec du programme

Exemplepublic class Lecture_mot { static BufferedReader input;

public static void main(String[] args) {

ouvrir_fichier("liste_mots");

traiter_fichier();

fermer_fichier(); }

// ouverture du fichier public static void ouvrir_fichier(String nom) { try {

input = new BufferedReader( new FileReader(nom));

}catch (IOException e) { System.err.println("Impossible d'ouvrir le fichier d'entree.\n" +

e.toString()); System.exit(1);}

} // ouvrir_fichier

Si on utilise juste cette ligne, et que "liste_mots" n’existe pas - une exception non traitée, le programme échoue

Possibilité de traiter l’exception ici, e.g. demander à l’utilisateur d’entrer un autre fichier

Message d’exception

catch (IOException e) {

System.err.println("Impossible d'ouvrir le fichier d'entree.\n" +

e.toString());

System.exit(1);

}

Message affiché:

Impossible d'ouvrir le fichier d'entree.

java.io.FileNotFoundException: liste_mots (No such file or directory)

Mécanisme général en Java

• Permet de détecter, signaler ou traiter une exception

• Non pour traiter des situations prévues

• N’est pas un mécanisme de contrôle pour le branchement d’un programme (if, …)– Mais plutôt un autre mécanisme qui contrôle

l’exécution

Mécanisme général• Exemples d’exemption

– Diviser par 0 – Accéder un tableau avec un index invalide

Méthode qui appelle:

Appel

Méthode appelée:

Normal

Exception

appel

Message d’exception

Suite normale

Traiter l’exception

Retour normal

Mécanisme général

• Deux mécanismes en parallèle– Traitement normal– Traitement d’exception (exception handler)

• Quand il y a une exception– Le traitement normal s’arrête– Le traitement d’exception prend le contrôle

Traitement d’exception en chaîne

• méthode_1 appelle méthode_2, qui appelle méthode 3

• Si méthode 3 génère une exception– Message d’exception est envoyé à méthode_2– Méthode_2 peut

• Traiter (attraper) l’exception• Relancer l’exception: le message d’exception sera envoyé à

méthode_1• …• Si une exception n’est traitée par aucune méthode qui appelle:

sortie du programme avec un message d’exception

Méthode_1 Méthode_2 Méthode_3

Exemple de transmission d’exception

Générer une exception

• Certaines exceptions standard sont reconnues– ArithmeticException: diviser par 0– ClassCastException: Casting d’un objet à une

mauvaise classe– EOFException: Lire après la fin d’un fichier– IllegalArgumentException: paramètres illégaux ou

inappropriés– …

• Quand une de ces exceptions est rencontrée, le système lance (throw) un message d’exception

Hiérarchie des classes d’exceptions

                                                                                                                                                                                                                                       

Attraper (catch) une exception• Attraper une exception pour la traiter

try {statements

: :} catch ( ExceptionClass1 object) {

statements :

:} catch (ExceptionClass2 object) {

statements : :} …

Bloc où une exception peut se

générer

Blocs pour attraper les exceptions

Exemple public static void ouvrir_fichier(String nom) { try {

input = new BufferedReader( new FileReader(nom));

}catch (IOException e) { System.err.println("Impossible d'ouvrir le fichier d'entree.\n" +

e.toString()); System.exit(1);}

}

Un autre exemplepublic void getSomeData () throws FileNotFoundException, SecurityException{

FileReader in;boolean success = false; //Data file openedint tryNumber = 0; //# of attempts to open datafileint delay = 5 * 1000; //wait in milli secswhile (!success) try {

tryNumber = tryNumber + 1;in = new FileReader(“DataFile”);success = true;…

} catch (SecurityException e) {if (tryNumber == 1)

thisThread.sleep(delay);else throw e;

}}

Exécution avec catch

• Si aucune exception est générée (thrown), les instructions dans catch ne sont pas exécutées

• Si une exception est générée, l’exception est comparée dans l’ordre avec les clauses de catch (ExceptionClass object)– Si la classe de l’exception match celle de catch:

• exécution des instruction de ce catch, • continue après le dernier catch (sauter les autres catches)

– Seulement le premier catch compatible avec l’exception est exécuté

• Important: Catch d’abord les sous-classes d’exception– Si aucun catch est compatible avec l’exception,

• l’exception n’est pas attrapée (non traitée)• transmise à la méthode qui appelle

Checked vs. Unchecked• Checked exception

– Vérifiée par le compilateur– Si le programme peut générer une telle exception, il doit

• Soit la traiter dans le programme• Soit la retransmettre à l’appelant (avec throws dans l’entête)

– Typiquement générée à cause de l’environnement– Exemple, IOException– public void getSomeData () throws FileNotFoundException,

SecurityException• Unchecked exception

– RuntimeException– Problème du programmeur (mauvaise utilisation d’une méthode,

d’un objet, …)– Le compilateur ne la vérifie pas– Si un programme peut générer une telle exception, le

programme n’a pas à la signaler dans l’entête– public int division(înt a, int b) {return a/b; }

Checked vs. Unchecked exception

Lancer une checked exception

• Signaler au compilateur qu’une méthode peut lancer une exception (non attrapée, non traitée)

public void methode() throws ExceptionClass• Exemple

public void skip () throws IOException {

String s;

s = input.readLine();

}

• Si une exception apparaît, transmise à l’appelant (caller)

Traitement partiel d’exceptionspublic void getSomeData () throws

FileNotFoundException, SecurityException{FileReader in;try { in = new FileReader (“DataFile”); …} catch (FileNotFoundException e) { //cleanup throw e; // throws it again to its caller}} catch (SecurityException e) { //cleanup throw e; // throws it again to its caller

}

finally

• Exécuter un bloc quel que soit l’exception try

{

statement

. . .

}

finally

{

statement

. . .

}

Exécuter finally même si le bloc try lance ne exception

finally• Souvent combiné avec catch

try{

statement . . . } catch (ExceptionClass exceptionObject){

statement . . .}finally{

statement . . .}

Même si une exception est attrapée, finally sera toujours exécuté

Utile pour s’assurer de certaine sécurité (cleanup)

Générer une exception explicitement• Un programme peut aussi générer une exception

public class BankAccount throws IllegalArgumentException{ public void withdraw(double amount) { if (amount > balance) { IllegalArgumentException exception = new IllegalArgumentException("Amount exceeds balance"); throw exception; } balance = balance - amount; } . . .}

• Général: throw exceptionObject; • Forcer la méthode qui appelle de traiter cette exception

Définir ses propres exceptions

• Les classes d’exception prédéfinies ne sont pas suffisamment explicites

• On a besoin de faire la différence entre les exceptions pour leurs traitements

• Définir une sous-classe d’exception

public class NoDataException extends Exception {public NoDataException () { super();}public NoDataException (String s) { super(s);}

}• Définir une hiérarchies de classes d’exception

constructeurs

Un autre exemple

class TemperatureException extends Exception {}

class TooColdException extends TemperatureException {}

class TooHotException extends TemperatureException {}

Classe Exception

• ConstructeursException() Constructs a new exception with null as its detail message.

Exception(String message) Constructs a new exception with the specified detail message.

Exception(String message, Throwable cause) Constructs a new exception with the specified detail message

and cause.

Exception(Throwable cause) Constructs a new exception with the specified cause and a detail

message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause).

Classe Throwable

• 4 constructeurs

• Thrwoable getCause()– Cause de cette exception (ou null)

• String getMessage(): – message envoyé par l’exception

• String toString()– Générer un message décrivant l’exception

• …

Penser Exception comme des classes / sous-classes

Une TooColdException est aussi une TempretureException, Exception, Throwable

Attention aux catches:

Catch une sous-classe avant une super-classe

Prévenir des erreurs

• Certaines erreurs peuvent être détectées ou éviter

• Tester la pré-conditon, post-condition ou l’invariant d’une méthode– Pré-condition: condition sous laquelle on l’appelle– Post-condition: condition après la méthode– Invariant: conditions devant être vérifiée tout au long

• Test sur pré-condition : facile (assert)• Test sur post-condition et invariant : plus difficile

assert

• assert booleanExpression ;• assert booleanExpression : expression

• Si la condition non satisfaite, AssertionError

• Exemple

//Interchange list.get(i) and list.get(j)// require 0 <= i, j < list.size() …private <Element> void interchange (

List<Element> list, int i, int j) {assert 0 <= i && i < list.size(): "precondition: illegal i";assert 0 <= j && j < list.size(): "precondition: illegal j";…

Alternative (public)

//Interchange list.get(i) and list.get(j)

// require 0 <= i, j < list.size() …

public <Element> void interchange (

List<Element> list, int i, int j)

{

if (0 <= i && i < list.size()) throw new IndexOutOfBoundsException("illegal i“);

if (0 <= j && j < list.size()) throw new IndexOutOfBoundsException("illegal j“);

Convention

• Méthode utilitaire private: assert• Méthode public: exception

– Pourquoi pas d’assert pour tester les paramètres ?• Ce test ne correspondent pas à la spécification de la

méthode public• Ne permettrait pas de générer un message d’exception

approprié

• Activer/Désactiver assertion:– Javac -enableassertions …– Javac -disableassertions …

Méthode private ou public

• Méthodes public:– Comportement observable de l’extérieur– défini par une spécification

• Méthode private– Méthode utilitaire pour faire un traitement

interne– N’est pas directement visible de l’extérieur– Non définie par une spécification

Exemple

• Définir une méthode qui fait retourne le plus petite valeur d’un tableau– Spécification:

• Accepter un tableau de nombres entiers• Retourner la plus petite valeur stockée• Cas spécial - tableau vide: un message

d’exception

– Entête

public int plusPetit(int [] a)

Implantation

• public int plusPetit(int [] a){

…return pp(a, 0);

}private int pp(int [] a, int ind){

…int p = pp(a, ind+1);if (p>a[ind]) return a[ind] else return p;

}

Utiliser Exception

Utiliser Assert

Recommended