TUTORIELS 
Les "exceptions" en Java : lever ses propres exceptions
Obtenir des messages d'erreurs appropriés à son programme, cela passe parfois par la création de ses propres exceptions. Voyons comment procéder.  (12 février 2002)
 

Après avoir introduit le principe des exceptions en Java et étudié plus finement la dernière fois les blocs try / catch / finally, nous allons maintenant nous intéresser à la conception de nos propres exceptions.

Créer sa propre exception permet de venir à bout d'une erreur à laquelle ne correspond aucune autre exception de manière prédéfinie ou plus simplement de distinguer un type d'erreur que l'on souhaite isoler du reste du programme.


La classe NegativeException

Rappelons tout d'abord qu'une exception n'a pas pour vocation de s'occuper de cas relativement fréquents, il faut en effet garder à l'esprit qu'elles sont consommatrices de ressources.

Afin de prendre un bon départ avec la création de ses propres exceptions, faisons-nous l'écho du premier tutoriel consacré aux exceptions :

"Une exception est en fait un objet crée lorsqu'une situation anormale se produit pendant l'exécution de votre programme. Les exceptions sont toujours issues de la classe Throwable. Deux sous-classes sont alors notables, elles sont dérivées de la classe Throwable et se nomment "Error" et "Exception"."

Ce petit résumé est toujours d'actualité ici. Nos exceptions seront considérées comme un objet qu'on peut "étendre". En pratique, il est conseillé de dériver ses classes d'exceptions à partir de classe "Exception". Ceci permet au compilateur de vérifier qu'une exception est capturée ou déclarée comme il se doit dans le programme. Il se souviendra également de l'endroit d'où l'exception a été lévée.


Notre exception doit contenir au minimum un constructeur par défaut qui va appeler celui de la classe de base. Exemple :

(NegativeException.java)
public class NegativeException extends Exception
{
     public NegativeException(String s)
     {
          super(s);
     }
}

Voici notre classe d'exception : "NegativeException". Pour resituer le contexte, notre petit programme affiche le résultat de l'opération "vitesse = distance / temps". Il est construit sur la base du programme qui jusqu'à maintenant nous servait d'exemple dans cette série de tutoriels ("ZeroDivide.java").

Ce nouveau programme (MyException.java) est donc capable d'intercepter les divisions par zéro (si le temps = 0 par exemple) mais également les distances négatives, c'est la raison de la conception de la classe "NegativeException".

Le mot-clef "extends" indique que notre classe est dérivée de la classe Exception (qui elle-même découle de Throwable).
Par convention notre classe comporte donc ce constructeur par défaut qui fait appel à celui de la classe parente (Exception) en lui passant son paramètre.
Le constructeur permet simplement de créer l'objet NegativeException lorsqu'une exception de ce type survient.

Nous stockons cette classe dans un fichier séparé (NegativeException.java) du reste du code, puis nous le compilons (javac NegativeException.java).


Le fichier principal

Rentrons dans le vif du sujet avec le code source de notre petit programme de calcul de vitesse :

(MyException.java)
class MyException
{
     public static void main(String[] args)
     {
          int d = 260;
          int t = 2;

          try
          {
               System.out.println("Vitesse : " + calcul(d,t) + " km/h");
          }

          catch(ArithmeticException e)
          {
               System.out.println("Une exception s'est produite ! (ArithmeticException) " +                                                    e.getMessage());
          }

          catch (NegativeException e)
          {
               System.out.println(e);
          }
     }

     static int calcul(int a, int b) throws NegativeException
     {
          if (a < 0)
          {
               throw new NegativeException("La distance est negative !");
          }
          
          return a/b;
     }
}

La gestion de la division par zéro est semblable à certains exemples que nous utilisions lors de tutoriels précédents, nous ne la détaillerons donc pas.

La nouveauté ici se situe dans la gestion des distances négatives. Ca n'est peut-être pas le meilleur exemple de création d'exception qu'il puisse exister mais si on considère que ce cas n'est pas très fréquent alors ce procédé ne pénalisera pas les performances.

Compilé et exécuté tel que présenté ici, ce programme affiche simplement :

Vitesse : 130 km/h

Si par contre on remplace la valeur d (distance) par son opposé (-260), on obtient dans ce cas à l'écran :

NegativeException : la distance est negative !

Comment avons-nous géré cette exception ?
De manière tout d'abord classique, nous avons encadré la portion de code susceptible de provoquer notre exception par un bloc try :

try
{
     System.out.println("Vitesse : " + calcul(d,t) + " km/h");
}

Etant donné que notre exception est une "checked exception" car découlant de la classe "Exception", nous devons prévoir les cas susceptibles de la déclencher. Le "catch" la concernant rejoint donc celui déjà présent relatif à la division par zéro. Nous avons ici deux blocs catch pour un même bloc try.
L'ordre des deux blocs catch n'importe pas ici vu que les deux sont dérivés d'une même classe (Exception). Si notre bloc catch était dérivé de la classe ArithmeticException, il faudrait le placer en première position (du cas le plus fin au plus général).

Notre méthode "calcul" est susceptible de lever une exception de type NegativeException, nous déclarons cet état de fait par la syntaxe suivante :

static int calcul(int a, int b) throws NegativeException

Par la suite nous lançons de manière conditionnelle (si la distance est négative) notre exception :

 throw new NegativeException("La distance est negative !");

La méthode stoppe dans ce cas son exécution. Par défaut le message de notre objet exception ne contient que le nom de notre classe, c'est pourquoi nous avons rajouté en paramètre le message "La distance est negative !", afin de rendre l'exception plus parlante.

 
[ Arnaud GadalJDNet
 
Accueil | Haut de page