Chapitre 10 - Gestion des erreurs avec les
exceptions
Recommandations pour les exceptions
Utilisez les exceptions pour :
- Fixer le problème et appeler la
méthode causant cette exception une nouvelle fois.
- Corriger les choses et continuez sans
ré-essayer la méthode.
- Calculer quelques résultats alternatif
à la place de ce que devrait produire la méthode.
- Faire ce que vous désirez dans le
contexte courant et relancer la même
exception dans un contexte plus haut.
- Faire ce que vous désirez dans le
contexte courant et lancer une exception différente
dans un contexte plus haut.
- Terminer le programme.
- Simplifier. (Si votre schéma d'exceptions
rend les choses plus compliqués, alors il est douloureux et
ennuyer à utiliser.)
- Rendre votre librairie et programme plus
sûr. (C'est un investissement à court-terme pour
le déboguage, et un investissement à long-terme
pour la robustesse de l'application.)
Résumé
La recherche amélioré d'erreur
>est l'une des puissantes voies qui peut augmenter la
robustesse de votre code. La recherche d'erreur est une
préoccupation fondamentale pour chaque programme que vous
écrivez, mais c'est surtout important en Java, où
l'un des buts primaire est de crée des composants de
programme pour d'autre utilisations. Pour créer un
système robuste, chaque composant doit être
robuste.
Les buts de l'identification d'exception en Java sont
de simplifier la
création de programmes larges, reliables en utilisant le
moins de code possible, et avec plus d'assurance que votre application
n'ai pas d'erreur non identifiée.
Les exceptions ne sont pas terriblement difficile à
apprendre, et
sont l'une des chose qui procurent des bénéfices
immédiat à votre
projet. Heureusement, Java impose tous les aspects des exceptions donc
cela garantie qu'elle seront employés
uniformément par à la fois les
concepteurs de librairies et les programmeurs clients.
Exercices
Les solutions aux exercices
sélectionnées peuvent
être trouvés dans le document
électronique The Thinking in Java Annotated
Solution Guide,, disponible pour une modique somme
à www.BruceEckel.com.
- Créez une classe avec un main()
qui lance un objet de la classe Exception dans un
bloc try. Donnez au constructeur d'Exception
un argument de type String. Piégez
l'exception dans une cause catch et affichez
l'argument du String. Ajoutez une cause finally
et affichez un message pour prouver que vous vous situez là.
- Créez votre propre classe d'exception
utilisant le mot-clé extends.
Écrivez un constructeur pour cette classe qui prendra un
argument de type String et stockez le dedans
l'objet par une référence au String.
Écrivez une méthode qui imprime en sortie le String
stocké. Créez une cause try-catch
pour exercer votre nouvelle exception.
- Écrivez une classe avec une
méthode qui lance une exception du type de celle
crée dans l'exercice 2. Éssayez de le compiler
sans spécification d'exception afin de voir ce que dit le
compilateur. Ajoutez la spécification d'exception
adéquate. Essayez en sortie votre classe et son exception
dans une cause try-catch.
- Définissez une
référence objet et initialisez la à null.
Essayez d'appeler cette méthode grâce à
cette référence. Maintenant enveloppez le code
dans une clause try-catch afin de capter
l'exception.
- Créez une classe ayant deux
méthodes, f() et g( ).
Dans g(), lancez une exception d'un nouveau type
que vous définirez. Dans f(), captez son
exception et, dans la clause catch, lancez une
exception différente (d'un second type que vous
définirez). Testez votre code dans main( ).
- Créez trois nouveaux types d'exceptions.
Écrivez une classe avec une méthode qui lance les
trois. Dans main(), appelez la méthode
mais en utilisant seulement une seule clause catch
qui piégera les trois types d'exceptions.
- Écrivez un code pour
générer et capter une ArrayIndexOutOfBoundsException.
- Créez votre propre comportement de
type-résurrection en utilisant une boucle while
qui se répète tant qu'une exception n'est pas
lancée.
- Créez une hiérarchie
à trois niveaux d'exceptions. Maintenant créez un
classe-de-base A avec une méthode qui
lance une exception à la base de votre
hiérarchie. Héritez B depuis A
et outrepassez la méthode afin qu'elle lance une exception
au second niveau de votre hiérarchie.
Répétez en faisant hériter la classe C
de la classe B. Dans main(),
créez un C et sur-typez le en A,
puis appelez la méthode.
- Démontrez qu'un constructeur d'une
classe-dérivé ne peut pas capter les exceptions
lancées par son constructeur de sa classe-de-base.
- Montrez que OnOffSwitch.java
peut échouer en lançant une RuntimeException
dans le bloc try.
- Montrez que WithFinally.java
n'échoue pas en lançant une RuntimeException
dans le bloc try.
- Modifiez l'Exercice 6 en ajoutant une clause finally.
Vérifiez que votre clause finally est
exécutée, même si une NullPointerException
est lancée.
- Créez un exemple où vous
utiliserez un drapeau pour contrôler si le nettoyage du code
est appelé, comme décrit dans le second
paragraphe après l'en-tête
« Constructors ».
- Modifiez StormyInning.java en
ajoutant une exception de type UmpireArgument, et
de les méthodes qui lancent cette exception. Testez la
hiérarchie modifiée.
- Enlevez la première cause
d'identification (catch) dans Human.java et
vérifiez que le code compile et s'exécute
toujours.
- Ajoutez un second niveau de perte d'exception
à LostMessage.java afin que HoHumException
soit lui-même remplacé par une
troisième exception.
- Dans le Chapitre 5, trouvez deux programmes
appelés Assert.java et modifiez les pour
lancer leur propres types d'exception au lieu d'imprimer vers System.err.
Cette exception doit être une classe interne qui
étends RuntimeException.
- Ajoute un jeu d'exceptions appropriés
à c08:GreenhouseControls.java.
[51]Le programmeur C peut regarder la valeur
renvoyée par printf()
en exemple à ceci.
[52] "2">C'est une amélioration
significative sur la
gestion d'exception de C++, qui ne piège pas les violations
des spécifications d'exceptions avant
l'exécution, quand ce n'est pas très utile.
[53]La gestion d'exception de C++ n'a pas de cause finally
parcqu'elle est reliée au destructeur pour accomplir ce type
de nettoyage.
[54]Un destructeur est une fonction qui est toujours
appelé
quand un objet devient inutilisé. Vous savez toujours
exactement où et quand le constructeur est
appelé. C++ possède des appels automatique au
destructeur, mais le Pascal Objet de Delphi dans ces versions 1 et 2
n'en a pas (ce qui change la pensée et l'usage du concept
d'un destructeur pour ce langage).<
[55]ISO C++ a ajouté des contraintes
similaires qui
nécessitent que les exceptions
dérivées-de-méthode soient les
même que, ou dérivées des, exceptions
lancées par la méthode de la classe-de-base.
C'est un cas dans lequel C++ est actuellement capable de rechercher des
spécifications d'exception au moment de la compilation.
[56]En C++, un destructeur
pourrait
gérer cela pour vous.