0% ont trouvé ce document utile (0 vote)
22 vues65 pages

03 Exceptions

Le document traite de la gestion des exceptions en Java, en distinguant les erreurs à l'exécution inévitables et évitables. Il explique comment utiliser les exceptions pour gérer les erreurs de manière séparée du flux normal d'exécution, permettant ainsi un code plus propre et maintenable. Des exemples illustrent la levée et la propagation des exceptions, ainsi que l'utilisation de blocs try-catch pour intercepter et traiter les erreurs.

Transféré par

aloulounarjes
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
22 vues65 pages

03 Exceptions

Le document traite de la gestion des exceptions en Java, en distinguant les erreurs à l'exécution inévitables et évitables. Il explique comment utiliser les exceptions pour gérer les erreurs de manière séparée du flux normal d'exécution, permettant ainsi un code plus propre et maintenable. Des exemples illustrent la levée et la propagation des exceptions, ainsi que l'utilisation de blocs try-catch pour intercepter et traiter les erreurs.

Transféré par

aloulounarjes
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Exceptions en Java (rappels)

Ing39 – Algorithmique Programmation Java

Serge Rosmorduc, Pierre Courtieu, Virginia Aponte


[Link]@[Link]
[Link]@[Link]
[Link]-garcia@[Link]
Conservatoire National des Arts et Métiers

9 septembre 2024
Erreurs à l’exécution

Erreurs à l’exécution inévitables :


▶ utilisateur tape un nom de fichier erroné
▶ réseau en panne
▶ librairie externe buggée
▶ bref : les bugs « externes »

Erreurs évitables
▶ non respect du contrat d’une fonction (ex : division par zéro)
▶ cas non prévus
▶ bref : les bugs « internes »
Comment gérer les erreurs ?

Évitables ou non, il faut traiter les erreurs éventuelles

Comment faire ?
1. Considérer les erreurs comme des résultats :
▶ une méthode retourne un code d’erreur
- problématique si notre méthode retournait déjà un résultat
(sur tout son co-domaine)
- souvent on ne veut/peut pas changer les méthode pour qu’elles
retournent un code d’erreur (ex : méthodes de la bibliothèque)
- dans le code : mélange de gestion des erreurs et des vrais
résultats

2. Utiliser des mécanismes spécifiques du langage


▶ non recommandables : break, jump...
▶ exceptions
Qu’est-ce que les exceptions ?

▶ exception = objet qui représente un message d’erreur


▶ qui interrompt le flux normal de l’exécution,
▶ qui va se propager dans le programme,
▶ et qu’on va (peut-être) traiter

▶ Aussi : mécanisme permettant de découpler les erreurs et leur


traitement
Motivation

lecture de trois entiers dans un fichier


f= ouvrir (nom );
i1= lire_entier (f);
i2= lire_entier (f);
i3= lire_entier (f);
fermer f;
Avec la manière artisanale : erreurs comme résultats…
si ((f= ouvrir (nom )) == 0)
affiche " fichier ␣non␣ ouvert "
exit 1
i1 = lire_entier (f);
si erreur_de_lecture gestion d'erreur intrusive !
affiche " entrée ␣non␣lue"
exit 1
i2 = lire_entier (f);
si erreur_de_lecture
affiche " entrée ␣non␣lue"
exit 1
i3 = lire_entier (f);
si erreur_de_lecture
affiche " entrée ␣non␣lue"
exit 1
fermer f;

Les codes applicatif et de gestion d’erreurs sont entrelacés …


Avec des exceptions
try {
f= ouvrir (nom );
i1= lire_entier (f);
i2= lire_entier (f);
i3= lire_entier (f);
fermer (f);
}
catch ( fichierNonOuvert e) {
afficher (" fichier ␣non␣ ouvert "); gestion séparée.
}
catch ( EntierNonLu e) {
fermer (f);
afficher (" fichier ␣mal␣formé ");
}
Explications
try {
f= ouvrir (nom ); // ouvre nom ou lève fichierNonOuvert
i1= lire_entier (f); // retourne un int ou lève EntierNonLu
i2= lire_entier (f); // retourne un int ou lève EntierNonLu
i3= lire_entier (f); // retourne un int ou lève EntierNonLu
fermer (f);
}
catch ( fichierNonOuvert e) {
afficher (" fichier ␣non␣ ouvert "); intercepte et traite
}
catch ( EntierNonLu e) {
fermer (f);
afficher (" fichier ␣mal␣formé ");
}
Explications
try {
f= ouvrir (nom );
i1= lire_entier (f); code protégé
i2= lire_entier (f);
i3= lire_entier (f);
fermer (f);
}
catch ( fichierNonOuvert e) {
afficher (" fichier ␣non␣ ouvert ");
}
catch ( EntierNonLu e) {
fermer (f);
afficher (" fichier ␣mal␣formé ");
}

Si l’un des appels protégés échoue, le reste est abandonné et on


tente un traitement avec les catch.
Logique du mécanisme d’exceptions

On aura plusieurs types de méthodes :


1. méthodes (propres ou externes) pouvant échouer
▶ elles signalent que leur résultat attendu n’a pas pu être
calculé/effectué
▶ cela signifie, qu’elles ne peuvent pas traiter l’erreur localement
▶ si une de leurs invocation échoue, l’exception est propagée à
travers la pile d’appel
▶ c’est logique : on recherche un traitement dans l’une de ses
méthodes appelantes

2. des méthodes qui les invoquent


▶ certaines contiendront des blocs de traitement
▶ qui interceptent les exceptions propagées par les méthodes qui
échouent
▶ qui proposent des actions de récupération
▶ et qui permettent la poursuite normale de l’exécution
Logique du mécanisme d’exceptions

méthode qui échoue

Recherche/Propagation/
Appel
Echec

méthode sans traitement

Appel
Recherche/Propagation/
Echec
méthode avec traitement

Appel Poursuite normale/ Retour


main
Instructions spécifiques aux exceptions

▶ throw
▶ « lève » une exception (signale une erreur )
▶ interruption de l’exécution du bloc courant (≃ break)
▶ propagation de l’exception : on remonte la pile d’appels à la
recherche d’un traitement
▶ si aucun traitement n’est trouvé, le programme complet
échoue

▶ try catch [finally]


▶ c’est un traitement :
▶ « intercepte »/« rattrape » le throw
▶ si le rattrapage réussi, reprise du flot normal d’exécution
Levée d’exception

1. Façons indirectes :
▶ appel d’une méthode pouvant lever une exception
(ex : [Link]("Abc") sur une chaîne qui ne
correspond pas à un entier)
▶ code pouvant déclencher une exception :
▶ accéder à un objet alors que le pointeur est nul
▶ division par zéro en entiers (pas en réels)
▶ accès à une case inexistante d’un tableau…

2. Explicitement avec l’instruction throw (sans « s ») :


if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣");

Notez qu’on utilise new pour créer l’exception qui est un objet.
Propagation d’exception
Si, pendant l’exécution d’une méthode P, une exception Exc survient :

1. interruption de l’exécution du code de P,


2. si aucun rattrapage-traitement de Exc n’est trouvé dans P :
▶ abandon des instructions de P restant à exécuter ⇒
2.1 P se termine anormalement, on dit que P échoue ;
2.2 on retourne vers la méthode qui a appelé P en propageant
Eexc ;
2.3 Dans la méthode appelante M, on recommence le processus :
(1) on cherche un traitement dans le code de M ; (2) si non
trouvé, échec de M et propagation vers la méthode G appelant
M;

Un déclenchement exception peut se propager dans la chaîne d’appels et


aboutir (transitivement) à l’échec au programme entier.
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) {
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) {
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1); appel d'une méthode...
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) {
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) {
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) {
a++; levée de l'exception
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) { de l'exception
propagation
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) { de l'exception
propagation
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) { de l'exception
propagation
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) {
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = arrêt
racinedu
(x);logiciel, affichage de la pile d'appels
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
}
Propagation d’une exception (sans traitement)
public class DemoPropagation {
public static int racine (int x) {
if (x < 0)
throw new IllegalArgumentException (" argument ␣ négatif ␣
+ x);
int a = 0;
while (a*a <= x) {
a++;
}
return a - 1;
}

public static void afficherRacine (int x) {


int rac = racine (x);
System .out. println (" racine ␣de␣"+ x+ "␣=␣"+ rac );
}

public static void main( String [] args) {


afficherRacine ( -1);
}
jamais exécutées
}
Pile d’appels (Stack trace)

Exception in thread "main" [Link]. IllegalArgumentException :


argument négatif -1
at [Link]( DemoPropagation .java :7)
at [Link]( DemoPropagation .java :1
at [Link]( [Link] :21)
Intercepter et traiter une exception
Bloc try-catch
Idée : protéger le code pouvant lever une exception par une construction
de d’interception et traitement d’exceptions, qui prévoit les instructions à
exécuter pour traiter ce type d’erreur .

try {
<code -protege -pouvant -echouer > // A
} catch (Exc e) {
<code - traitement > // B
}
<code -apres -bloc -try -catch > // C

▶ Si A ne lève aucune exception, on poursuit avec C


▶ Si A lève Exc, on exécute B, puis on poursuit avec C
▶ Si A lève une autre exception, le bloc courant échoue, à la recherche
d’un traitement dans un bloc englobant. Si non trouvé, la méthode
courante échoue, et l’exception est propagée à la méthode
appelante.
Comportement selon le placement du try-catch
public static int racine(int x) {
if (x < 0) throw new IllegalArgumentException ("argument␣négatif␣" +
int a = 0;
// etc ...
}

public static void afficherRacine(int x) {


int rac = racine(x);
[Link]("racine␣de␣"+ x+ "␣=␣"+ rac);
}

Dans le main
public static void main(String [] args) {
try { afficherRacine (-1);
} catch ( IllegalArgumentException e) {
[Link]("Calcul␣impossible␣" + [Link] ()); }
[Link]("le␣programme␣se␣termine␣normalement ...");
}
Comportement selon le placement du try-catch
public static int racine(int x) {
if (x < 0) throw new IllegalArgumentException ("argument␣négatif␣" +
int a = 0;
...
}

public static void afficherRacine(int x) { Dans une autre méthode


String affichage;
try {
int rac = racine(x);
affichage = "racine␣de␣" + x + "␣=␣" + rac;
} catch( IllegalArgumentException e) {
affichage = "racine␣de␣" + x + "␣n'existe␣pas"; }
[Link](affichage );
}
ici, main ne voit
pas l'exception
public static void main(String [] args) {
afficherRacine (-1);
[Link]("le␣programme␣se␣termine␣normalement ...");
}
Laisser passer les exceptions

Important !!!!
Quand on ne sait pas quoi faire d’une exception, on la laisse
passer !!!!!
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé

▶ catch : exécuté ou non


▶ finally : toujours exécuté, même si aucune exception levée
Traitements multiples, finally

... C1 code non protégé


try { code « protégé »
... C2 ...
} exécuté si throw(ExcA) dans C2
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
... exécuté si throw(ExcB) dans C2
finally { exclusivement, pas dans CA!
... codefinal ...
} « quoi qu'il arrive »
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... pas d'exception
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... pas d'exception
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... pas d'exception
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé

▶ Déroulement non exceptionnel


Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcB)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcB)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
On peut utiliser les données stockées dans e
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcB)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcB)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé

▶ Exception interceptée
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcC)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcC)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... } aucun catch ne correspond
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcC)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... } aucun catch ne correspond
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcC)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... } aucun catch ne correspond
...
finally {
... codefinal ... Propagation de l'exception ExcC
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcC)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... } aucun catch ne correspond
...
finally {
... codefinal ... Propagation de l'exception ExcC
}
... C3 code non protégé

Code non exécuté


▶ Exception non interceptée
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ...
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcA)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcA)!
}
catch (ExcA e) { ... CA ... }
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcA)!
}
catch (ExcA e) { ... CA ... } throw(ExcB)!
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé

▶ Exception de C2 interceptée dans le handler


Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcA)!
}
catch (ExcA e) { ... CA ... } throw(ExcB)!
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ...
}
... C3 code non protégé

▶ Exception de C2 interceptée dans le handler


▶ mais pas d’interception pour un lancement venant d’un catch
Traitements multiples, finally

... C1 code non protégé


try {
... C2 ... throw(ExcA)!
}
catch (ExcA e) { ... CA ... } throw(ExcB)!
catch (ExcB e) { ... CB ... }
...
finally {
... codefinal ... Propagation de l'exception ExcB
}
... C3 code non protégé

Code non exécuté


▶ Exception de C2 interceptée dans le handler
▶ mais pas d’interception pour un lancement venant d’un catch
▶ finally exécuté puis propagation si exception non interceptée
Exceptions et héritage

▶ les catch sont pris dans l’ordre


▶ on exécute premier compatible (règle de l’affectation) avec
l’exception interceptée
▶ permet de jouer avec l’héritage et d’avoir un grain plus ou
moins fin.

Puisque FileNotFoundException étend IOException, 2 choix :

try { try {
.. code levant des IOExceptions .. code levant des IOExceptions
.. dont FileNotFoundException .. dont FileNotFoundException
} catch (IOException e) { } catch ( FileNotFoundException e) {
//... traite de la même manière // traitement de FileNotFoundExceptio
// } catch (IOException e) {
toutes les IOExceptions // autres IOExceptions
} }
Ordre des catch et héritage

Puisque FileNotFoundException étend IOException, si on


écrit :
try {
... code levant des IOExceptions
... dont FileNotFoundException
} catch (IOException e) {
//... autres IOExceptions
} catch ( FileNotFoundException e) {
//... traitement de FileNotFoundException
}

▶ le catch de FileNotFoundException n’est jamais exécuté ;


▶ le compilateur le détecte et refuse de compiler !
Exceptions déclarées
public static int f1 (int x) throws Exception {

Signature d’une méthode :


▶ attribut(s), type de retour, nom de la méthode, types des
paramètres

public static String lireFichier (File f) throws IOException {


FileReader r = new FileReader (f);
... // autre code qui manipule r...
r. close ();
return resultat ;
}
Exceptions déclarées
public static int f1 (int x) throws Exception {

Signature d’une méthode :


▶ attribut(s), type de retour, nom de la méthode, types des
paramètres
+ exceptions possibles

public static String lireFichier (File f) throws IOException {


FileReader r = new FileReader (f);
... // autre code qui manipule r...
r. close ();
return resultat ;
}
Exceptions déclarées
public static int f1 (int x) throws Exception {

Signature d’une méthode :


▶ attribut(s), type de retour, nom de la méthode, types des
paramètres
+ exceptions possibles
▶ quand on laisse passer une exception, Java force à la déclarer
(mot clef throws, notez le « s »)
▶ sauf les RuntimeException : il y aurait des throws partout
▶ sauf pour les Error : on ne peut pas les traiter

public static String lireFichier (File f) throws IOException {


FileReader r = new FileReader (f);
... // autre code qui manipule r...
r. close ();
return resultat ;
}
Exceptions déclarées

▶ Les exceptions déclarées sont une spécificité de Java ;


▶ leur existence est assez logique ;
▶ mais souvent considérées comme une mauvaise idée ;
▶ spring, par exemple, les évite.
À éviter

▶ catch vide : cache l’exception sous le tapis, ne jamais faire,


sauf si :
1. vous vous attendez à ce que l’exception se produise ;
2. et vous voulez ne rien faire dans ce cas-là
3. …et continuer l’exécution du programme comme si de rien
n’était.
▶ catch du type :
try {
...
} catch ( UneException e) {
e. printStackTrace ();
}

traitement en cours continue comme si pas d’exception.


Du bon usage des exceptions
▶ les exceptions servent à signaler un problème ;
▶ elles ne sont pas une structure de contrôle « normale »
▶ préférer quand c’est possible un test avec un if à une
exception :
plutôt
File f = ....;
if (f. exists ()) {
FileReader r = new FileReader (f);
...
}
que :
File f = ....;
try {
FileReader r = new FileReader (f);
...
} catch ( FileNotFoundException e) {
...
}
(honnêtement, pour ce cas précis, ça passe encore…)

Vous aimerez peut-être aussi