next up previous contents index
Next: 11 Tableaux et chaînes Up: Java: Le langage Previous: 9 Packages

Subsections

10 Exceptions

   La gestion des erreurs sans un programme est une activité importante et souvent complexe dans les langages classiques. Bien des erreurs dans les programmes proviennent d'une mauvaise gestion des erreurs. La méthode utilisée en C , par exemple, pour la gestion des erreurs est de tester l'état d'une variable ou d'un retour de fonction pour savoir si tout s'est bien passé. Rien n'oblige un programmeur du langage C à tester rigoureusement les conditions d'erreurs. Et bien des programmes ne le font pas de manière exhaustive. Il n'y a aucune aide pour structurer cette gestion d'erreurs.

Avec les exceptions , le langage Java propose une approche radicalement différente de l'approche traditionnelle. Qu'est ce qu'une exception ? Une exception est une sorte de signal qui indique qu'une erreur ou une situation remarquable est intervenue. On dira qu'une méthode ayant détecté une situation anormale déclenche (throw) une exception. Cette exception sera capturée (catch) par le code.

On distingue deux types d'erreurs : les exceptions et les erreurs . Les erreurs sont généralement des erreurs fatales et le programme s'arrête après déclenchement de ce type d'erreurs. Les exceptions ne sont pas constitués uniquement des erreurs produites pas des ``erreurs systèmes''. Le concepteur d'une classe peut définir des erreurs (non fatales) pour assurer la robustesse du code. Par exemple, le débordement d'un tableau est une erreur qui est déclenchée et qui n'est pas une erreur fatale.

Il existe encore quelques méthodes qui rendent des valeurs que l'on doit interpréter comme des cas d'erreurs (comme en C ), mais il s'agit généralement des situation ou l'erreur n'est pas très grave.

Lorsqu'une méthode déclenche une exception, la machine Java remonte la suite des invocations de méthodes jusqu'à atteindre une méthode qui capture cette exception. Si aucune méthode capturant cette exception n'est trouvée, alors l'exécution s'arrête.

L'utilisation des exceptions permet de

10.1 Qu'est-ce qu'une exception

Une exception ou erreur est un objet de la classe java.lang.throwable et toutes les exceptions et erreurs sont des sous classes de la classe java.lang.throwable :

 
public class Throwable extends Object {
    // Constructeurs publiques
    public Throwable();
    public Throwable(String message);
    // Méthodes publiques
    public Throwable fillnStackTrace();
    public String getMessage();
    public void printStackTrace();
    public void printStackTrace(PrintStream s);
    public String toString();
}
 
public class Error extends Throwable {
    // Constructeurs publiques
    public Error();
    public Error(String s);
}
 
public class Exception extends Throwable {
    // Constructeurs publiques
    public Exception ();
    public Exception (String s);
}
A chaque objet des classes est associé un message qui peut être obtenu avec la méthode getMessage() de la classe java.lang.throwable.

10.2 Définir de nouveaux types d'exception

Les exceptions sont des objets d'une classe dérivée de la classe Exception. Imaginons que l'on veuille fournir un code sûr pour notre classe Date. Par exemple, la méthode affecter devrait produire une exception si les entiers fournis en paramètres de cette méthode n'est pas cohérent avec une date. On va, à présent, définir une exception DateNonConforme.

 
public class DateNonConforme extends java.lang.Exception {
    public DateNonConforme(String e) {
        super("Date non Conforme:" + e);
        ...
    }
}
Pourquoi donc définir une nouvelle classe alors qu'on pourrait pu tout simplement créer un objet de la classe Exception ? Les raisons pour lesquelles on préférera créer une nouvelle classe dérivée sont les suivantes :

10.3 Déclencher des exceptions

Chaque méthode qui est susceptible d'émettre une exception doit le déclarer dans l'entête son entête. Il s'agit des exceptions qui lui sont propres et non pas toutes celles déclenchées par les invocations des méthodes qu'elle contient. Pour reprendre l'exemple de notre classe Date, la méthode affecter devrait déclencher une exception lorsque ses paramètres ne correspondent pas à une date.

 
public void affecter(int j, int m, int a) throws DateNonConforme {
    ...
    if (m >= 1 && m <= 12) this.mois = m;
    else throw new DateNonConforme(" mois " + m);
    ...
}
Le ou les exceptions levées par une méthode doivent absolument être déclarées dans l'entête. Si les exceptions à déclarer dans l'entête sont oubliées ou déclarées de manière incomplète, il y aura une erreur à la compilation. Lorsqu'une méthode lève plusieurs exceptions, elles seront séparées par des virgules dans l'entête de la méthode.
 
void une_methode(...) throws Except1, ..., Exceptn { ... }

10.4 Capturer les exceptions

10.4.1 Le bloc try

Les exceptions levées par une méthode doivent être capturées par la méthode appelante. Pour ce faire, on aura pris soin d'encapsuler l'appel de la méthode dans un bloc try.

 
...
try {
    ...
    une_methode(...)
    ...
}
catch (typeException1 identificateur1) {
    ...
    }
...
catch (typeExceptionn identificateurn) {
    ...
    }
finally  {
    ...
}
La fin du bloc try contient toute la gestion des exceptions à l'aide des clauses catch. Elle ne sont pas obligatoires; il peut y avoir un nombre arbitraire de clauses catch (éventuellement nul).

10.4.2 Les clauses catch

Les instructions du corps du bloc try sont exécutées jusqu'à la fin de ce bloc si aucune exception n'est levée. Dans le cas contraire, le contrôle est transféré à l'une des clauses catch. Si aucune clause catch n'est prévue pour traiter cette exception, le contrôle est transféré à la dernière des méthodes appelantes englobées dans un bloc try et ainsi de suite.

Si une clause finally existe à la fin d'un bloc try, le contrôle est passé à cette portion du code dans tous les cas :

10.4.3 Les clauses finally

La clause finally est utilisée lorsque l'état d'un système doit être mise à jour quelque soit la manière dont les instructions se sont exécutées. Par exemple, un bloc de code qui crée un fichier doit fermer ce fichier à la fin du traitement.

Le code contenu dans une clause finally ne peut être ignoré : il n'existe aucun moyen de quitter un bloc try sans exécuter le bloc finally.

10.4.4 Les exceptions non capturées

Comme nous l'avons déjà dit, une méthode peut ignorer la gestion d'une exception à condition qu'elle ``retransmette'' l'exception à la méthode appelante. Pour cela, il suffit que la méthode qui reçoit une exception déclare dans son entête qu'elle la retransmet.

 
...
public void une_methode(...) throws DateNonConforme {
    ...
    Date d = new Date(200, 56, -2);
    ...
}

10.5 Les classes Error, Exception et RuntimeException

Toutes les erreurs et exception sont des sous classes de la classe Throwable. La figure 10.1 donne la hiérarchie des ces classes.

Throwable Les seules exceptions qu'il n'est pas nécessaire de préciser dans la clause throws sont les RuntimeException et Error et leurs extensions.

Les objets de la classe Error sont des erreurs relativement grave et une application n'est pas sensée la capturée. De même, une application Java n'est sensée lancer ce type d'erreurs.

Une application Java ne travaille généralement qu'avec des objets de la classe Exception. Dans ce cas, il s'agit ``d'erreurs'' au sens large, qu'une application est susceptible de lancer. Comme nous l'avons vu, on crée des sous classes pour définir des exceptions propres à chaque application.

Parmi ces sous classe, il en existe une prédéfinie qui est la classe RuntimeException. Ce type d'exception à la particularité de pouvoir être ignoré par les applications. Contrairement aux exceptions pures, il n'y aura pas d'erreurs de compilation si ce genre d'exception ne sont pas capturées.

10.6 Les blocs statiques

.

 

A TERMINER


next up previous contents index
Next: 11 Tableaux et chaînes Up: Java: Le langage Previous: 9 Packages
Touraivane
6/12/1998