# Java/Exceptions
## Introduction

Pour avoir un programme robuste, il faut gérer les erreurs qui peuvent subvenir lors de l'exécution du programme.
Une erreur ou une exception se produit lorsque les conditions d'exécution sont telles que la poursuite du programme devient impossible ou incorrecte. Par exemple il peut s'agir d'un débordement de tableau, d'un manque de mémoire, d'une division par zéro ou même, comme nous allons le voir par la suite, d'une exception levée par le programmeur.
Cela oblige à écrire de nombreux tests qui n'ont pas de rapport direct avec la tâche principale du programme.
Ce n’est pas toujours facile avec les langages classiques, tel le C où le seul moyen de gérer les exceptions est de retourner des constantes comme 0 ou -1 par une méthode pour signifier que son exécution s'est respectivement déroulée sans ou avec problème...
Java propose une approche très différente :

## Qu'est-ce qu'une exception

C'est un objet de la classe java.lang.Throwable, classe mère de toutes les erreurs et exceptions. Cette classe a pour sous-classes :
* java.lang.Error dont doivent hériter les erreurs graves qui causent l'arrêt du programme comme par exemple la classe OutOfMemoryError,
* java.lang.Exception dont doivent hériter les erreurs qui doivent impérativement être traitées ou capturées comme par exemple la classe FileNotFoundException,
* java.lang.RuntimeException, qui hérite de java.lang.Exception, et dont doivent hériter les erreurs qui peuvent ne pas être traitées ou capturées, comme par exemple les classes NullPointerException, NumberFormatException ou encore ArrayIndexOutOfBoundsException.

## Capturer une exception

Lorsqu'une exception est lancée, elle se propage d'une méthode à la méthode appelante jusqu'à être capturée. Si elle ne l'est pas, le programme s'arrête et le contenu de la pile des méthodes traversées est indiqué à l'utilisateur.
Syntaxe d'une interception :
Si une erreur survient dans le bloc d'instructions n$^o$ 1, l'interpréteur le quitte immédiatement et une exception est levée. Comme nous nous trouvons dans un bloc try/catch elle sera peut être attrapée par le catch correspondant, auquel cas son bloc d'instructions sera exécuté. Si aucun des catch présents ne l'attrapent, l'erreur se propage à la méthode appelante et ainsi de suite. Dans tous les cas le bloc finally (facultatif) est exécuté, même en présence d'un return dans le bloc n$^o$ 1 exécuté sans erreur.
Depuis la version 7 de Java, il est possible d'utiliser le catch de multiple Exceptions :
Un exemple continuant celui de l'introduction :
À noter que de nombreuses méthodes de la bibliothèque Java (l'API Java) peuvent générer des exceptions. C’est le cas par exemple de la méthode de classe int Integer.parseInt(String) qui a pour fonction de convertir une chaîne de caractères en un entier (par exemple "123" en l'entier 123). Si la chaîne ne contient pas un nombre, la méthode lève une NumberFormatException. Comme cette exception n'a pas obligation à être interceptée (cf. #Qu'est-ce qu'une exception), il n’est pas impératif, quoique conseillé, de placer chaque appel à int Integer.parseInt(String) au sein d'un bloc try/catch.

## Méthodes de l’objet Exception

* printStackTrace : affiche l'état de la pile lors de la remontée de l'exception. Utile pour trouver les causes de celle-ci.

## Lancer une exception

Une exception peut être lancée via la syntaxe suivante :
où exception est une expression dont la valeur doit être un objet de type Throwable.
Si une méthode est susceptible de lancer une exception de type T ou U, elle doit :
* soit l'attraper via un bloc try/catch adéquat,
* soit déclarer qu'elle est susceptible de laisser échapper des exceptions via l’expression throws T, U placée en fin d'en-tête de méthode (cf. l'en-tête du constructeur de la classe Point ici et là).

## Créer son propre type d'exception

On le peut en héritant de la class Exception :
Le constructeur de la classe Point de l’exemple introductif peut alors s'écrire :

## Exceptions courantes

| Héritage et polymorphisme | Gestion de fichiers |