Gerer les exceptions

 

Des exceptions peuvent se produire durant l'exécution de votre méthode.

Ces exceptions peuvent être liées à des erreurs de logique dans votre code ou à des cas particuliers comme une division par 0.

Il existe deux types d'exceptions:

Les exceptions contrôlées: Il s'agit d'exceptions qu'une méthode peut déclencher au cas où une erreur est rencontrée. Elles sont contrôlées par le compilateur car elles doivent être prises en compte dans vos classes (exemple les exceptions déclenchées par des méthodes d'entrées/sorties). Deux manières de traiter l'exception: Soit elle traite elle même l'exception en l'interceptant, soit elle laisse l'exception remonter à la méthode appelante.

Les exceptions non contrôlées: A vous de voir si vous voulez que votre programme les traite ou non. Si c'est non, la JVM affichera un message indiquant l'erreur et l'endroit où l'exception s'est déclenchée.

Lorsqu'une exception est déclenchée, la JVM va remonter les informations de la pile d'exécution pour trouver la première méthode capable d'intercepter et de traiter l'exception. Si la JVM n'en trouve pas, alors elle prend en charge le traitement en arrêtant le traitement et en affichant dans la console l'exception qui vient de se produire et sa localisation.

 

Intercepter et traiter les exceptions

Il sera possible (et même pour les exceptions contrôlées, il sera obligatoire) d'intercepter des exceptions avec les instructions try catch. (Heureusement, Eclipse va vous mâcher le travail pour les exceptions contrôlées).

Le principe étant de mettre dans le try la portion de code qui risque de générer une exception et dans le(s) catch(s) le(s) traitements des exception(s).

En complément, il y a l'instruction finally. Cette instruction permet d'effectuer une portion du code et ce dans tous les cas, que le code dans le try se déroule bien ou non.

Cette commande est par exemple à utiliser pour fermer systématiquement l'utilisation des filtres de flux. Hélas, on ne le trouve pas assez souvent dans les exemples sur internet !

Vous trouverez des exemples avec l'utilisation des filtres de flux.

 

NoteIl est possible de mettre plusieurs instructions catch pour gérer tous les cas d'exceptions qui peuvent se produire dans votre bloc try. Il est cependant à noter qu'un ordre de déclaration est à respecter. Les exceptions sont des classes ou des sous classes d'autres exceptions. Les sous classes d'exceptions devront être déclarées avant la classe mêre. Sinon, vous obtiendrez un message d'erreur lors de la compilation. Celui-ci vous indiquera que l'exception est déjà traitée ([...]exception java.lang.nom_de_l_exception has already been caught).

 

Propager/lever une exception

Il est possible de propager/lever une exception dans une méthode de classe volontairement. Par exemple, lorsque votre méthode reçoit un paramètre qui n'est pas cohérent avec le traitement que doit effectuer votre méthode.

Vous utiliserez pour cela l'instruction throw suivie d'une instance d'une classe d'exception.

Dans l'exemple, vous auriez un code du style:

if (paramètre invalide)

throw new IllegalArgumentException ("Le paramètre " + parametre + " n'est pas valide.");

AttentionDans le cas d'une exception dérivant d'une exception contrôlée, la méthode qui sera à l'origine de l'exception devra en plus indiquer qu'elle est susceptible de lever cette exception (cf. chapitre suivant : Laisser remonter des exceptions contrôlées). Sinon, il y aura erreur à la compilation, le compilateur considérant que la méthode ne traite pas l'exception alors qu'elle le doit (ce qui est faux dans ce cas) !

 

Liste (non exhaustive) de classes d'exception

Sur le site d'Oracle, vous trouverez une liste détaillée des exceptions

Les classes dérivées de java.lang.RuntimeException et java.lang.Error sont des exceptions non contrôlées. A vous de les traiter ou non dans vos programmes.

On notera les plus courantes comme java.lang.ArithmeticException pour une division par zéro.

java.lang.IndexOutOfBoundsException pour un indice hors limite et les sous classes java.lang.ArrayIndexOutOfBoundsException (pour un tableau) et java.lang.StringIndexOutOfBoundsException (pour une chaîne de caractères)

 

Les classes dérivées de java.lang.Exception sont elles contrôlées. Vous devez coder vos méthodes pour les prendre en compte. Heureusement, Eclipse va vous simplifier la vie à ce niveau en vous proposant de générer le code.

On notera :

java.io.IOException et dérivées pour les erreurs d'entrée/sortie.

java.sql.SQLException et dérivées pour les erreurs sur bases de données.

 

 

Exceptions métiers

Il est possible de créer sa propre exception. Il faudra pour cela dériver de la classe Exception pour avoir une exception contrôlée ou de RuntimeException, voire une sous-classe des classes précédemment citées.

Il n'y aura pas grand chose à coder dans ses classes (voire rien à part un séquenceur de serialization):

Cependant, on trouve souvent dans ces classes une méthode recevant un message qui détail l'erreur. Il sera donc intéressant d'avoir ce genre de méthode qui se contentera de lancer la méthode équivalente de la classe mêre.

Rien n'empêchera d'ajouter d'autres méthodes.

NoteEclipse pourra vous générer automatiquement la classe est toutes les méthodes dérivants de la classe mêre.

AttentionDans le cas d'une exception dérivant d'une exception contrôlée, la méthode qui sera à l'origine de l'exception devra indiquer qu'elle est susceptible de lever cette exception (cf. chapitre suivant : Laisser remonter des exceptions contrôlées). Sinon, il y aura erreur à la compilation, le compilateur considérant que la méthode ne traite pas l'exception alors qu'elle le doit (ce qui est faux dans ce cas) !

 

Laisser remonter des exceptions contrôlées

Il est possible de ne pas traiter directement une exception contrôler dans votre méthode mais de la laisser remonter à la méthode appelante.

Il y a au moins un cas où vous serez obligé d'utiliser cette commande: Lorsque votre méthode propage une exception contrôlée. Etant donné qu'elle est à l'origine de la propagation, elle ne va sûrement pas traiter elle même cette exception !

Ce cas peut être nécessaire pour n'avoir qu'une seule méthode qui traitera l'exception.

Vous utiliserez la clause throws au niveau de la signature des méthodes. Il sera possible d'indiquer une à plusieurs exceptions. Dans ce cas, vous utiliserez la virgule pour lister l'ensemble des exceptions après la clause throws

AttentionLa clause throws se fait sur les méthodes et non les classes. Le compilateur n'en voudra de toute façon pas !

public void maMethode () throws ClasseExceptionControlees/métier [, ClasseExceptionControlees/métierSuivante [, la suite des exceptions...]]

{

...throw new ClasseExceptionControlees/métier ("Le paramètre " + parametre + " n'est pas valide.");...

}

 

Exemple de code utilisant l'exception contrôlée personnalisée

Voici une exception contrôlée qui étend la classe Exception

 

Une classe TstExcep a une méthode add qui va déclencher cette exception

Et enfin une classe qui déclenche tout:

 

Intercepter toutes les exceptions

Il sera enfin possible d'intercepter toutes les exceptions en utilisant la classe Throwable dont sont issues toutes les classes d'exceptions.

Voici un exemple:

Qui permet de traiter particulièrement l'exception ArithmeticException et de manière groupé toutes les autres exceptions dans le else.