US

Générer des exceptions

Hiérarchie de classes des exceptions

Toutes les exceptions qui peuvent apparaitre dans un programme Java sont, on l'a vu à la section précédente, représentées par des classes Java. Ces classes sont organisées d'une certaine manière afin de former la hiérarchie de classes illustrée sur la figure j11.4.

Hiérarchie de classes des exceptions
fig j11.5 Hiérarchie de classes des exceptions

Comme pour toutes les classes Java, la classe mère est bien entendu la classe Object. Juste en dessous, on retrouve la classe mère des erreurs : la classe Throwable qui représente toute entité pouvant être générée suite à une erreur. nEsuite, on peut voir deux branches : la branche Error et la branche Exception.

La branche Error

Les classes qui se trouvent dans cette branche représente des erreurs graves qu'une application ne devrait pas gérer. En effet, les erreurs que l'on retrouve dans cette branche sont des erreurs qui surviennent dans des conditions anormales, erreurs qui ne devraient pas apparaitre dans les cas normaux.

On retrouve 4 sous-classes de Error :

  • LinkageError : Indique qu'une classe dépend d'autres éléments qui sont indisponibles.
  • ThreadDeath : Exception reçue par un thread qui meurt.
  • VirtualMachineError : Indique un problème au niveau de la machine virtuelle Java : manque de ressources, ou JVM cassée.
  • AWTError : Exception qui est générée lorsqu'une erreur grave au niveau d'AWT apparait.

La branche Exception

Dans cette branche, on retrouve des erreurs plus communes comme par exemple ArithmeticException qui représente une erreur d'arithmétique comme une division par zéro, NullPointerException qui apparait lorsqu'on travaille sur une variable de type objet qui contient la référence null, ArrayIndexOutOfBoundsException qui apparait lorsque l'on travaille avec les tableaux et qu'on tente d'accéder à un indice inexistant, ...

Les exceptions de cette branche sont donc celles que l'on va pouvoir attraper avec une instruction try-catch pour effectuer un traitement particulier. Remarquez enfin qu'on retrouve un partie séparée à cette branche : RuntimeException, on y reviendra très bientôt.

Générer une exception

Imaginons que l'on souhaite écrire une méthode qui permet de calculer la factorielle d'un nombre entier positif n. Pour rappel, la factorielle de n est notée n! et se calcule comme n = 1 . 2 . 3 . ... . n, et on a 0!=1.

Voyons tout d'abord une première manière d'écrire cette méthode. On va utiliser une précondition pour s'assurer que la méthode est bien appelée avec un entier positif.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
/**
* Calcul de la factorielle d'un nombre
*
* @pre n >= 0
* @post La valeur renvoyée contient la factorielle de n
*/
public int fact (int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
listing j11.10 La méthode fact

Cette solution est assez élégante, mais si vous vous rappelez du chapitre 7, on y disait qu'on n'aime pas qu'il y aie trop de préconditions. On va donc tenter de la supprimer, mais alors, comment gérer le cas où n est négatif ?

Avec la spécification qu'on a mise là, on va se retrouver avec soit une valeur arbitraire ou alors la méthode ne se finit pas (boucle infinie), mais dans ces deux cas, il sera difficile pour celui qui utilise la méthode de savoir si tout s'est bien passé ou non.

Une première solution est d'utiliser une valeur spéciale pour le cas où n est négatif, par exemple -1.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
/**
* Calcul de la factorielle d'un nombre
*
* @pre -
* @post La valeur renvoyée contient la factorielle de n si n >= 0
* sinon, elle contient -1
*/
public int fact (int n)
{
    if (n <= 0) return -1;
 
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
listing j11.11 La méthode fact avec valeur spéciale

Voilà, maintenant, la personne qui utilise cette méthode va pouvoir savoir si tout s'est bien passé ou non en consultant la valeur de retour de la méthode. On peut utiliser une valeur spéciale quand on en dispose, en effet, par définition la factorielle d'un nombre est toujours positive, on peut donc utiliser tous les nombres négatifs pour signaler divers problèmes.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
int n = -4;
int r = fact (n);
if (r == -1)
{
    System.out.println ("La factorielle d'un négatif n'existe pas");
}
else
{
    System.out.println ("La factorielle de %d est %d\n", n, r);
}
listing j11.12 Utilisation de la méthode fact avec valeur spéciale

Mais comment faire lorsqu'on ne peut pas renvoyer une valeur spéciale ? Et bien, on pourrait par exemple générer une exception. Ainsi, la personne utilisant la méthode n'aurait qu'à attraper l'exception avec une instruction try-catch.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
int n = -4;
try
{
    int r = fact (n);
    System.out.println ("La factorielle de %d est %d\n", n, r);
}
catch (ArithmeticException exception);
{
    System.out.println ("La factorielle d'un négatif n'existe pas");
}
listing j11.13 Utilisation de la méthode fact avec exception

L'instruction throw

L'instruction throw permet de générer une exception. Pour l'utiliser, il faut lui fournir une référence vers un objet de type Exception. Revoyons notre exemple de factorielle, et générons une ArithmeticException si le n fourni est négatif.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
/**
* Calcul de la factorielle d'un nombre
*
* @pre -
* @post La valeur renvoyée contient la factorielle de n si n >= 0
* @throw ArithmeticException si n < 0
*/
public int fact (int n)
{
    if (n <= 0) throw new ArithmeticException();
 
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
listing j11.14 La méthode fact avec exception

Voilà, c'est aussi simple que ça de générer une exception. L'instruction throw permet de générer une exception, donc, si le flux de contrôle arrive à une instruction throw, l'exception est générée, le flux de contrôle quitte immédiatement la méthode et l'exception est propagée, remontant les appels de méthodes jusqu'à rencontrer un catch ou jusqu'à la méthode main où le programme s'arrête avec un message d'erreur comme on l'a vu à la section précédente.

Vous aurez aussi remarqué la spécification de la méthode qui a changé. En effet, lorsque qu'une méthode est susceptible de générer une exception, il faut ajouter une ligne avec @throw NomDeLexception Explication.

Exceptions sous et hors-contrôle

On retrouve deux catégories d'exceptions en Java : les exceptions sous-contrôle et les exceptions hors-contrôle. Ce qui différencie les deux types d'exceptions, c'est l'analyse de la propagation de celles-ci. La propagation des exceptions sous-contrôles est analysée pendant la compilation du programme, ce qui n'est pas le cas pour les exceptions hors-contrôle.

Qu'est-ce-que cela implique ? Et bien, si une méthode est susceptible de générer une exception sous-contrôle et que vous faites un appel vers cette méthode, pendant la phase de compilation, le compilateur va se rendre compte qu'une exception pourrait survenir, et donc, vous allez être obligé de mettre une instruction try-catch sans quoi le programme ne compilera pas.

Par contre, pour les exceptions hors-contrôle, vous ne serez pas obligé de les attraper. Toute les exceptions qui étendent la classe Exception sont des exceptions sous-contrôle, sauf toute la branche dont la classe mère est la classe RuntimeException.

Les exceptions hors-contrôle sont donc comme les erreurs de type Error, à savoir que, dans un programme normal, elles ne devraient pas être attrapée et gérée.

Comment le compilateur va-t'il savoir si une méthode est susceptible ou pas de générer une exception ? Il faut ajouter l'information dans l'entête de la méthode grâce à un nouveau mot réservé : throws (à ne pas confondre avec throw).

Les exceptions sous-contrôle offrent plus de sécurité et de garantie, en effet, l'utilisateur d'une méthode va donc devoir gérer l'exception, soit il la capture, soit il la laisse se propager. On va voir tout ça la section suivante.

  • Espace membre
  • Learning Center
  • Les forums
  • Livre d'or
  • Imprimer
  • Boutique
  • Info
  • Règlement
  • Erreur
  • Newsletter

MyPagerank.Net

Firefox 3.6

Browse Happy logo

Open Clip Art Library

Join our Facebook Group

Twitter

Copyright © 2000-2013 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Valid XHTML 1.1 !
Valid CSS2 !
Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0
ICRA Internet Content Rating Association
Creative Commons License
Site optimisé pour Firefox avec une résolution 1024x768 --- Page chargée en 0.2502561 secondes --- This site uses Thumbshots previews