Exceptions

publicité
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
Exemple
public class Lecture_mot {
static BufferedReader input;
public static void main(String[] args) {
ouvrir_fichier("liste_mots");
traiter_fichier();
fermer_fichier();
}
Si on utilise juste cette
ligne, et que "liste_mots"
n’existe pas - une
exception non traitée, le
programme échoue
// 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
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
Appel
Méthode appelée:
…
Retour normal
Suite
normale
Normal
Traiter
l’exception
…
Exception
Message d’exception
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
Méthode_1
Méthode_2
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
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
Bloc où une exception
try {
statements
:
:
} catch ( ExceptionClass1 object) {
statements
:
:
} catch (ExceptionClass2 object) {
statements
:
:
}…
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 exemple
public void getSomeData () throws FileNotFoundException, SecurityException
{
FileReader in;
boolean success = false; //Data file opened
int tryNumber = 0;
//# of attempts to open datafile
int delay = 5 * 1000; //wait in milli secs
while (!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’exceptions
public 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
...
Même si une exception est
}
finally
{
statement
...
}
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();
constructeurs
}
public NoDataException (String s) {
super(s);
}
}
• Définir une hiérarchies de classes d’exception
Un autre exemple
class TemperatureException extends Exception {
}
class TooColdException extends TemperatureException {
}
class TooHotException extends TemperatureException {
}
Classe Exception
• Constructeurs
Exception()
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)
{
Utiliser Exception
…
return pp(a, 0);
}
private int pp(int [] a, int ind)
{
Utiliser Assert
…
int p = pp(a, ind+1);
if (p>a[ind]) return a[ind] else return p;
}
Téléchargement