Vous êtes sur la page 1sur 8

Chapitre 10

Les exceptions
10.1 Introduction : quest-ce quune exception ?
De nombreux langages de programmation de haut niveau poss`edent un mecanisme permettant de
gerer les erreurs qui peuvent intervenir lors de lexecution dun programme. Le mecanisme de gestion
derreur le plus repandu est celui des exceptions. Nous avons dej`a aborde le concept dexception dans
le cours sur les fonctions : lorsquune fonction nest pas definie pour certaines valeur de ses arguments
on l`eve une exception en utilisant le mot clef throw. Par exemple, la fonction factorielle nest pas
definie pour les nombres negatifs, et pour ces cas, on l`eve une exception :
Listing 10.1 (lien vers le code brut)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

class Factorielle {
s t a t i c int f a c t o r i e l l e ( int n ){
int res = 1;
i f ( n <0){
throw new P a s D e f i n i ( ) ;
}
f o r ( i n t i = 1 ; i <= n ; i ++) {
res = res i ;
}
return r e s ;
}
}
c l a s s P a s D e f i n i e x t e n d s E r r o r {}

Une exception signale une erreur comme lorsquun nombre negatif est passe en argument a` la
fonction factorielle. Jusquici, lever une exception signifiait interrompre definitivement le programme
avec laffichage dun message derreur decrivant lexception a` lecran. Cependant, il est de nombreuses situations o`u le programmeur aimerait gerer les erreurs sans que le programme ne sarrete
definitivement. Il est alors important de pouvoir intervenir dans le cas o`u une exception a e te levee.
Les langages qui utilisent les exceptions poss`edent toujours une construction syntaxique permettant
de rattraper (ou recuperer) une exception, et dexecuter un morceau de code specifique a` ce traitement derreur.
Examinons maintenant comment definir, lever et recuperer une exception en Java.
1

CHAPITRE 10. LES EXCEPTIONS

10.2 Definir des exceptions


Afin de definir une nouvelle sorte dexception, on cree une nouvelle classe en utilisant une declaration
de la forme suivante :
class NouvelleException extends ExceptionDejaDefinie {}
On peut remarquer ici la presence du mot cle extends, dont nous verrons la signification dans un
chapitre ulterieur qui traitera de lheritage entre classes. Dans cette construction, NouvelleException
est le nom de la classe dexception que lon desire definir en etendant ExceptionDejaDefinie
qui est une classe dexception dej`a definie. Sachant que Error est predefinie en Java, la declaration
suivante definit la nouvelle classe dexception PasDefini :
class PasDefini extends Error {}
Il existe de nombreuses classes dexceptions predefinies en Java, que lon peut classer en trois
categories :
Celles definies par extension de la classe Error : elles representent des erreurs critiques
qui ne sont pas censees e tre gerees en temps normal. Par exemple, une exception de type
OutOfMemoryError est levee lorsquil ny a plus de memoire disponible dans le syst`eme.
Comme elles correspondent a` des erreurs critiques elles ne sont pas normalement censees e tre
recuperees et nous verrons plus tard que cela permet certaines simplifications dans lerciture de
methodes pouvant lever cette exception.
Celles definies par extension de la classe Exception : elles representent les erreurs qui
doivent normalement e tre gerees par le programme. Par exemple, une exception de type IOException
est levee en cas derreur lors dune entree sortie.
Celles definies par extension de la classe RuntimeException : elles representent des erreurs pouvant e ventuellement e tre gerees par le programme. Lexemple typique de ce genre
dexception est NullPointerException, qui est levee si lon tente dacceder au contenu
dun tableau qui a e te declare mais pas encore cree par un new.
Chaque nouvelle exception entre ainsi dans lune de ces trois categories. Si on suit rigoureusement
ce classement (et que lon fait fi des simplifications e voquees plus haut), lexception PasDefini
aurait due e tre declaree par :
class PasDefini extends Exception {}
ou bien par :
class PasDefini extends RuntimeException {}
car elle ne constitue pas une erreur critique.

10.3 Lever une exception


Lorsque lon veut lever une exception, on utilise le mot cle throw suivi de lexception a` lever,
quil faut avoir cree e auparavant avec la construction new NomException() Ainsi lancer une
exception de la classe PasDefini secrit :
throw

new PasDefini();

10.4. RATTRAPER UNE EXCEPTION

Lorsquune exception est levee, lexecution normale du programme sarrete et on saute toutes les
instructions jusqu`a ce que lexception soit rattrapee ou jusqu`a ce que lon sorte du programme. Par
exemple, si on consid`ere le code suivant :
Listing 10.2 (lien vers le code brut)
1
2
3
4
5
6
7
8
9
10
11
12
13

public clas s Arret {


p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
i nt x = Terminal . l i r e I n t ( ) ;
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 1 ) ;
i f ( x >0){
throw new S t o p ( ) ;
}
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 2 ) ;
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 3 ) ;
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 4 ) ;
}
}
c l a s s S t o p e x t e n d s R u n t i m e E x c e p t i o n {}

// 1

// 2
// 3
// 4

lexecution de la commande java Arret puis la saisie de la valeur 5 (pour la variable x) produira
laffichage suivant :
Coucou 1
Exception in thread "main" Stop
at Arret.main(Arret.java:7)
Cest-`a-dire que les instructions 2, 3 et 4 nont pas e te executees. Le programme se termine en indiquant que lexception Stop lancee dans la methode main a` la ligne 7 du fichier Arret.java na
pas e te rattrapee.

10.4 Rattraper une exception


10.4.1 La construction try catch
Le rattrapage dune exception en Java se fait en utilisant la construction :
Listing 10.3 (pas de lien)
1
2
3
4
5
6

try {
... // 1
} catch ( UneException e ) {
... // 2
}
.. // 3

Le code 1 est normalement execute. Si une exception est levee lors de cette execution, les instructions restantes dans le code 1 sont abandonnees. Si la classe de lexception levee dans le bloc 1 est
UneException alors le code 2 est execute (car lexception est recuperee). Dans le code 2, on peut
faire reference a` lexception en utilisant le nom donne a` celle-ci lorsque lon nomme sa classe. Ici le
nom est e. Dans le cas o`u la classe de lexception nest pas UneException, le code 2 et le code 3
sont sautes. Ainsi, le programme suivant :

CHAPITRE 10. LES EXCEPTIONS

Listing 10.4 (lien vers le code brut)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

public clas s Arret2 {


public s t a t i c void P ( ) {
i nt x = Terminal . l i r e I n t ( ) ;
i f ( x >0){
throw new S t o p ( ) ;
}
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 1 ) ;
try {
P ();
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 2 ) ;
} catch ( Stop e ){
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 3 ) ;
}
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 4 ) ;

// 1

// 2
// 3
// 4

}
}
c l a s s S t o p e x t e n d s R u n t i m e E x c e p t i o n {}

produit laffichage suivant lorsquil est execute et que lon saisit une valeur positive :
Coucou 1
Coucou 3
Coucou 4
On remarquera que linstruction 2 nest pas execute (du fait de la levee de lexception dans P.
Si on execute ce meme programme mais en saisissant une valeur negative on obtient :
Coucou 1
Coucou 2
Coucou 4
car lexception nest pas levee.
En revanche le programme suivant, dans lequel on l`eve une exception Stop2, qui nest pas
recuperee.
Listing 10.5 (lien vers le code brut)
1
2
3
4
5
6
7
8
9
10
11

public clas s Arret3 {


public s t a t i c void P ( ) {
i nt x = Terminal . l i r e I n t ( ) ;
i f ( x >0){
throw new S t o p 2 ( ) ;
}
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 1 ) ;
try {

// 1

10.4. RATTRAPER UNE EXCEPTION


12
13
14
15
16
17
18
19
20
21

P ();
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 2 ) ;
} catch ( Stop e ){
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 3 ) ;
}
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 4 ) ;

// 2
// 3
// 4

}
}
c l a s s S t o p e x t e n d s R u n t i m e E x c e p t i o n {}
c l a s s S t o p 2 e x t e n d s R u n t i m e E x c e p t i o n {}

produit laffichage suivant lorsquil est execute et que lon saisit une valeur positive :
Coucou 1
Exception in thread "main" Stop2
at Arret3.P(Arret3.java:7)
at Arret3.main(Arret3.java:15)

10.4.2 Rattraper plusieurs exceptions


Il est possible de rattraper plusieurs types dexceptions en enchanant les constructions catch :
Listing 10.6 (lien vers le code brut)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

public clas s Arret3 {


public s t a t i c void P ( ) {
i nt x = Terminal . l i r e I n t ( ) ;
i f ( x >0){
throw new S t o p 2 ( ) ;
}
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
// 1
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 1 ) ;
try {
P ();
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 2 ) ;
// 2
} catch ( Stop e ){
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 3 ) ;
// 3
}
} catch ( Stop2 e ){
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 3 b i s ) ; / / 3 b i s
}
// 4
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 4 ) ;
}
}
c l a s s S t o p e x t e n d s R u n t i m e E x c e p t i o n {}
c l a s s S t o p 2 e x t e n d s R u n t i m e E x c e p t i o n {}

A lexecution, on obtient (en saisissant une valeur positive) :


Coucou 1
Coucou 3 bis
Coucou 4

CHAPITRE 10. LES EXCEPTIONS

10.5 Exceptions et methodes


10.5.1 Exception non rattrapee dans le corps dune methode
Comme on la vu dans les exemples precedents, lorsquune exception est levee lors de lexecution
dune methode et quelle nest pas rattrapee dans cette methode, elle continue son trajet a` partir de
lappel de la methode. Meme si la methode est sensee renvoyer une valeur, elle ne le fait pas :
Listing 10.7 (lien vers le code brut)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

public clas s Arret {


s tat i c int lance ( int x) {
i f ( x < 0) {
throw new S t o p ( ) ;
}
return x ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
int y = 0;
try {
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 1 ) ;
y = lan ce ( 2);
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 2 ) ;
} catch ( Stop e ) {
T e r m i n a l . e c r i r e S t r i n g l n ( Coucou 3 ) ;
}
T e r m i n a l . e c r i r e S t r i n g l n ( y v a u t +y ) ;
}
}
c l a s s S t o p e x t e n d s R u n t i m e E x c e p t i o n {}

A lexecution on obtient :
Coucou 1
Coucou 3
y vaut 0

10.5.2 Declaration throws


Lorsquune methode l`eve une exception definie par extension de la classe Exception il est
necessaire de preciser au niveau de la declaration de la methode quelle peut potentiellement lever une
exception de cette classe. Cette declaration prend la forme throws Exception1, Exception2,
... et se place entre les arguments de la methode et laccolade ouvrant marquant le debut du corps de
la methode. On notera que cette declaration nest pas obligatoire pour les exceptions de la categorie
Error ni pour celles de la categorie RuntimeException.

10.6 Exemple resume


On reprend lexemple de la fonction factorielle :
Listing 10.8 (lien vers le code brut)


10.6. EXEMPLE RESUM
E
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

class Factorielle {
s t a t i c i n t f a c t o r i e l l e ( i n t n ) t hro ws P a s D e f i n i { / / ( 1 )
int res = 1;
i f ( n <0){
throw new P a s D e f i n i ( ) ;
/ / (2)
}
f o r ( i n t i = 1 ; i <= n ; i ++) {
res = res i ;
}
return r e s ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
int x ;
T e r m i n a l . e c r i r e S t r i n g ( E n t r e z un nombre ( p e t i t ) : ) ;
x = Terminal . l i r e I n t ( ) ;
try {
/ / (3)
Terminal . e c r i r e I n t l n ( f a c t o r i e l l e ( x ) ) ;
} catch ( PasDefini e ) {
/ / (3 b is )
T e r m i n a l . e c r i r e S t r i n g l n ( La f a c t o r i e l l e de
+x+ n e s t p a s d e f i n i e ! ) ;
}
}
}
c l a s s P a s D e f i n i e x t e n d s E x c e p t i o n {}
/ / (4)

Dans ce programme, on definit une nouvelle classe dexception PasDefini au point (4). Cette
exception est levee par linstruction throw au point (2) lorsque largument de la methode est negatif.
Dans ce cas lexception nest pas rattrapee dans le corps et comme elle nest ni dans la categorie
Error ni dans la categorie RuntimeException, on la declare comme pouvant e tre levee par
factorielle, en utilisant la declaration throws au point (1). Si lexception PasDefini est levee lors
de lappel a` factorielle, elle est rattrapee au niveau de la construction try catch des points (3)
(3 bis) et un message indiquant que la factorielle du nombre entre nest pas definie est alors affiche.
Voici deux executions du programme avec des valeurs differentes pour x (lexception est levee puis
rattrapee lors de la deuxi`eme execution) :
> java Factorielle
Entrez un nombre (petit):4
24
> java Factorielle
Entrez un nombre (petit):-3
La factorielle de -3 nest pas d
efinie !

Annexe : quelques exceptions predefinies


Voici quelques exceptions predefinies dans Java :
NullPointerException : utilisation de length ou acc`es a` un case dun tableau valant
null (cest a` dire non encore cree par un new).
ArrayIndexOutOfBoundsException : acc`es a` une case inexistante dans un tableau.
ArrayIndexOutOfBoundsException : acc`es au ieme caract`ere dun chane de caract`eres
de taille inferieure a` i.

CHAPITRE 10. LES EXCEPTIONS

ArrayIndexOutOfBoundsException : creation dun tableau de taille negative.


NumberFormatException : erreur lors de la conversion dun chane de caract`eres en
nombre.
La classe Terminal utilise e galement lexception TerminalException pour signaler des erreurs.

Vous aimerez peut-être aussi