LA GESTION DES EXCEPTIONS
Abdellaziz Walid Département G-Info
[Link]@[Link] 2023-2024
Motivation 1
2
Question : Pourquoi tous les aéroports du monde recevant des avions de lignes
doivent obligatoirement compter une équipe de pompiers qui s’entraîne très
régulièrement, malgré la rareté des incendies ?
Réponse : Selon les normes de protection contres les incendies, l’intervention à
l’endroit le plus éloigné de la piste d’un aéroport doit être faite en moins de 3
minutes après le déclenchement de l’alerte afin d’évacuer tous les passagers à bord
de l’avion.
Motivation 2 : Contexte de programmation
3
Class Operation Programme principale
public final class Operation{ import [Link];
public static double division( double p, class Main {
double q)
public static void main(String args[]) {
{
double p, q, r;
return p / q;
[Link]("Enter two real
} numbers for Division: ");
public static double somme( double p, Scanner sc = new Scanner([Link]);
double q)
p = [Link]();
{
q = [Link]();
return p+q;
r = [Link](p,q);
}
[Link]("The result of the
……… } Division = "+r);} }
Questions : - Y-a-t’il une exception dans ce programme ?
- Ce programme prévoit-t-il et gère-t-il les exceptions ?
Exception : contexte de programmation
4
Une exception est un évènement qui arrive durant l’exécution d’un
programme qui interrompt le déroulement normal des instructions.
Plusieurs erreurs très différentes peuvent provoquer des exceptions,
d’un problème matériel, manque de mémoire, ,des actions
imprévues de l'utilisateur, …etc.
Lorsque ce genre de chose arrive, il donne l’impression que le
logiciel n’est pas robuste. D’où :
Nécessité de prévoir que le logiciel sera soumis à des défaillances dues
à certains paramètres externes ou internes(exceptions).
Prévoir une réponse adaptée à chaque type de situation(exception).
L’objectif principal est d’améliorer la qualité de " robustesse " d’un
logiciel.
Application sans gestion d’exceptions
5
Class Operation Programme principale
public final class Operation{ import [Link];
public static double division( double p, class Main {
double q) public static void main(String args[]) {
{ Erreur si q=0 qui
double p, q, r;
return p / q; provoquera l’arrêt
du programme [Link]("Enter two real
} numbers for Division: ");
public static double somme( double p, Scanner sc = new Scanner([Link]);
double q) p = [Link]();
{ q = [Link]();
Si l’utilisateur
return p+q; tape 0
r = [Link](p,q);
} [Link]("The result of the
……… } Division = "+r);} }
La JVM arrêterait le programme immédiatement à cet endroit parce qu'elle n'aurait pas trouvé de
code d'interception de cette exception qui serait automatiquement levée.
Comment gérer l’exception ?
6
Programme principale
import [Link];
class Main {
- Solution 1 : Détecter et
public static void main(String args[]) { gérer l’exception au niveau
double p, q, r; du programme principale.
[Link]("Enter two real numbers for Division: ");
Scanner sc = new Scanner([Link]); - Problème : la réutilisation
p = [Link](); de la classe Operation dans
q = [Link](); un autre programme ou
if q!=0 { application provoquera un
r = [Link](p,q);
arrêt immédiat du
programme.
[Link]("The result of the Division = "+r);}
else
[Link](“Error : Division by zero = ");}}
Comment gérer l’exception ?
7
Classe Operation
public final class Operation{
public static double division( double p, double q) {
- Solution 2 : Détecter et gérer
if q!=0 l’exception au niveau local.
return p / q; - Problème : quoi retourner
else { effectivement en cas d’erreur.
[Link](“Error : Division by zero = "); - Très mauvaise solution car il
return ???????????? produit des effets de bord :
Affichage dans le terminal
}
alors que ce n’est pas du tout
public static double somme( double p, double q)
le rôle de méthode division.
{
return p+q;
}
……… }
Comment gérer l’exception ?
8
Classe Operation
public final class Operation{ Solution3 : déjà meilleur
public static Boolean division( double p, double q, double r) { car elle laisse à la fonction
if q!=0 { qui appelle la méthode
r=p/q;
division quoi faire en cas
d’erreur.
return true
Mais elle présente des
}
inconvénients :
else - Cas de l’appel d’appel
return false d’appel …. d’appel de
} fonction.
public static double somme( double p, double q) - Écriture peu intuitive
{ division(x,y,z) au lieu
return p+q; de z=division(x,y) :
}
division est un
opérateur binaire
……… }
Une autre solution mais efficace
9
Il existe une solution efficace permettant de généraliser et
d’assouplir cette dernière solution :
Déclencher et traiter une exception.
Il se base sur un mécanisme permettant de :
Prévoir une erreur à un endroit;
De la gérer à un autre endroit;
De ne pas mettre fin au programme.
Mécanisme de gestion des exceptions
10
Principe :
Lorsque une erreur a été détectée à un endroit, on la signale
en « lançant » un objet contenant toutes les informations
que l’on souhaite donner sur l’erreur.
À l’endroit où l’on souhaite gérer l’erreur (au moins
partiellement), on peut « attraper » l’objet « lancé ».
Si un objet « lancé » n’est pas attrapé du tout, cela
provoque l’arrêt du programme : toute erreur non gérée
provoque l’arrêt.
Un tel mécanisme s’appelle « gestion des exceptions ».
Illustration du mécanisme de gestion des exceptions
11
Class Operation Programme principale
public final class Operation{ import [Link];
public static double division( double p, class Main {
double q) public static void main(String args[])
{
Lancement d’une {
return p / q; exception (objet) double p, q, r;
} [Link]("Enter two real
public static double somme( double p, numbers for Division: ");
double q) Scanner sc = new Scanner([Link]);
{ p = [Link]();
return p+q; Si l’utilisateur
q = [Link]();
tape 0
} r = [Link](p,q);
……… } [Link]("The result of the
Division = "+r);} }
Cette fois pas d’arrêt de l’exécution du programme Rattraper et traiter l’objet
Gestion des exceptions : contexte Java
12
Dans Java, on cherche à remplir 4 tâches élémentaires :
A. Signaler une erreur (exception).
B. Marquer les endroits réceptifs aux erreurs (exceptions).
C. Leur associer (à chaque endroit réceptif) un moyen de
gérer les erreurs(exceptions) qui se présentent.
D. Éventuellement, « faire le ménage » après un bloc
réceptif aux erreurs.
Syntaxe de gestion des exceptions
13
On a donc 4 mots du langage Java dédiés à la gestion
des exceptions :
1. throw: indique l’erreur (c-à-d lance l’exception)
2. try : indique un bloc réceptif aux erreurs
3. catch : gère les erreurs associées ou exceptions (i.e. les
« attrape » pour les traiter)
4. Finally : (optionnel) indique ce qu’il faut faire après un
bloc réceptif
Illustration du mécanisme de gestion des exception
par java
14
Class Operation Programme principale
import [Link];
public final class Operation{ class Main {
public static double division( double p, public static void main(String args[]) {
double q) double p, q, r;
{ [Link]("Enter two real numbers for Division:
if (q==0) { ");
try { // bloc pour attraper l’objet (bloc réceptif
throw ……….. // lancer l’exception(objet)
d’erreurs)
} Scanner sc = new Scanner([Link]);
return p / q; p = [Link]();
} Si l’utilisateur
q = [Link]();
tape 0
public static double somme( double p, r = [Link](p,q);
double q) { [Link]("The result of the Division = "+r);}
return p+q;} Catch (…….) { //bloc pour rattraper et traiter l’erreur }
……… } Finally {…………..} // bloc pour faire ménage
Cette fois pas d’arrêt de l’exécution du }}
programme
Synthèse
15
Une exception est un moyen de signaler un événement nécessitant
une attention spéciale au sein d’un programme, comme :
Une erreur grave.
Une situation inhabituelle devant être traitées de façon particulière.
But : améliorer la robustesse des programmes en :
Séparant le code du traitement de l’exception du code effectif.
Fournissant le moyen de forcer une réponse à des erreurs
particulières.
throw
16
throw est l’instruction qui signale l’erreur au reste du
programme.
Syntaxe java : throw exception;
exception : est un objet de type de la classe Exception qui est
lancé au reste du programme pour être « attrapé »
Exemple :
throw new Exception("my first exception");
Remarque:
Exception est une classe de [Link] qui possède plusieurs sous
classes et qui hérite de la classe Throwable.
Exemple de throw
17
public final class Operation{
public static double division( double p, double q)
{
if (q==0) {
throw new Exception("Division par zéro");
}
return p / q;
}
public static double somme( double p, double q)
{
return p+q;
}
……… }
La classe [Link]
18
public class Throwable extends Object
- Posséde deux constructeurs (avec et sans message) :
- public Throwable()
- public Throwable (String message)
- Deux méthodes (parmi d’autres) :
- Accès au message d’erreur :
public String getMessage()
- Affichage du chemin vers l’erreur :
public void printStackTrace()
Hiérarchie partielle de Throwable
19
Les exceptions
non contrôlées
(unchecked
exceptions)
Les exceptions
contrôlées
(checked
exceptions)
• Error correspondent à des exceptions ou erreurs fatales car elles sont engendrées
par la JVM. Le développeur n’est pas censé d'attraper et traiter (try/catch) ce
genre d’erreurs.
• Les RuntimeException que l'on peut rattraper et traiter mais que l'on n'est pas
obligé.
• Les exceptions contrôlées que l'on est obligé d'attraper (try/catch) ou de dire que
la méthode appelante devra s'en occuper (throws).
Hiérarchie partielle de Throwable
20
Exemple de throw avec un objet plus spécifique
21
public final class Operation{
public static double division( double p, double q)
{
if (q==0) {
throw new ArithmeticException("Division par zéro");
}
return p / q;
}
public static double somme( double p, double q)
{
return p+q;
}
……… }
try
22
try :
Introduit un bloc réceptifs aux exceptions lancées par des instructions, ou des
méthodes appelées par des méthodes ……..appelées à l’intérieur du bloc.
Exemple :
public static void main(String args[])
{
double p, q, r;
[Link]("Enter two real numbers for Division: ");
Scanner sc = new Scanner([Link]);
try {
p = [Link]();
q = [Link]();
r = [Link](p,q);
[Link]("The result of the Division = "+r); }}
}
catch
23
Le mot clé catch introduit un bloc dédié à la gestion d’une ou
plusieurs exceptions.
Tout bloc try doit toujours être suivi d’au moins un bloc catch
gérant les exceptions pouvant être lancées dans ce bloc try.
Si une exception est lancée mais n’est pas interceptée par le
catch correspondant, le programme s’arrête (message
« Exception in thread… » et affichage de la trace
d’exécution).
Syntaxe :
catch (type nom) {……..}
Intercepte toutes les exceptions de type type lancées depuis
le bloc try précédent.
type peut être une classe prédéfinie de la hiérarchie
d’exceptions de Java ou une classe d’exception créer par le
programmeur.
Exemple de catch
24
try {…….
}
catch (IOException ex) {
[Link](ex);
throw ex;
}
catch (SQLException ex) {
[Link](ex);
throw ex;
}
À partir de java 7 : multi-catch : traiter plusieurs types d’ exceptions par un seul bloc
catch
catch (IOException | SQLException ex | ………)
{
[Link](ex);
throw ex;
}
Syntaxe : try and catch
25
N.B :
S’il y a plusieurs blocs catch toujours les indiquer du plus spécifique
au plus général (sinon erreur signalée par le compilateur).
Exemple : try and catch
26
Exception spécifique
Exception générale
try\throw\catch dans la même méthode
27
finally
28
Le bloc finally est optionnel, il suit les blocs catch.
finally est optionnel.
Il contient du code destiné à être exécuté qu’une exception ait
été lancée ou pas par le bloc try.
Le but de finally est de faire le ménage (fermer des fichiers,
des connexions etc…).
Déclaration d’une exception
29
Une méthode lançant une exception sans la traiter localement doit
généralement informer qu’il le fait.
La syntaxe pour déclarer une exception est :
Type methode (….) throws Exception1, Exception 2, ……
Exemple :
public static double division( double p, double q) throws ArithmeticException
{
if (q==0) {
throw new ArithmeticException("Division par zéro");
}
return p / q;
}
}
Règle : déclarer ou traiter
30
Toute les exceptions contrôlées (cheked exceptions) en dehors
des RunTimeException et des Error (uncheked exceptions) :
Soit être interceptées dans la méthode où elles sont lancées.
Soit être déclarées par la méthode.
Sinon : le compilateur émettra un message d’erreur.
Problème : manque d’informations
31
Manque d’informations
Lever une exception qui porte comme information « Division par zéro»
sans préciser l’élément de la liste où se trouve le zéro.
Solution : Relancement
32
Une exception peut être partiellement traitée par un bloc catch
et attendre un traitement plus complet à un niveau supérieur.
Il suffit pour cela de relancer l’exception au niveau du bloc
n’effectuant que le traitement partiel.
Il faudra pour cela que l’appel à ce bloc de catch soit lui-
même dans un autre bloc try à un niveau supérieur.
Exemple de relancement
33
Relancement de l’exception pour capturer l’indice de l’élément qui a levé l’exception
Lever une exception qui porte comme
information « Division par zéro»
Exceptions personnalisées
34
Dans Java, il est possible de programmer ses propres classes
d’exception soit :
Comme sous classe de la classe Exception
Comme sous classe d’une sous classe existante de Exception
Contenu minimal :
Classe MonException extends Exception
{
public MonException() {
Super("mon message par défaut");
}
Public MonException(String message) {
Super(message);
}
}
Exceptions personnalisées
35
Il est possible de définir dans une sous classe
d’exception personnalisée tout membre jugé utile :
Code d’erreur.
Informations sur le contexte de détection de
l’exception.
etc…
Exemple : Exception personnalisée
36
Exemple : Exception personnalisée (try … catch)
37
Conclusion
38
Lancer des exceptions plus informatif et utile.
Si l’erreur peut être levée et traiter là où elle est découverte, il
faut le faire sans la traiter à un niveau supérieur.
La gestion d’une exception coûte beaucoup plus en temps
qu’une simple structure de contrôle conditionnelle (if … then
… else)
L’utilisation des exceptions avec leur mécanisme intégré,
autorise la construction rapide et efficace de logiciels robustes.