Java/Exceptions
Introduction
[modifier | modifier le wikicode]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 :
class Point {
public static final int X_MAX = 1024, Y_MAX = 768;
private int x, y;
public Point (int a, int b) throws Exception {
if (a < 0 || a >= X_MAX || b < 0 || b >= Y_MAX) {
throw new Exception("Coordonnées illégales.");
}
x = a;
y = b;
}
}
Qu'est-ce qu'une exception
[modifier | modifier le wikicode]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 classeOutOfMemoryError
,java.lang.Exception
dont doivent hériter les erreurs qui doivent impérativement être traitées ou capturées comme par exemple la classeFileNotFoundException
,java.lang.RuntimeException
, qui hérite dejava.lang.Exception
, et dont doivent hériter les erreurs qui peuvent ne pas être traitées ou capturées, comme par exemple les classesNullPointerException
,NumberFormatException
ou encoreArrayIndexOutOfBoundsException
.
Capturer une exception
[modifier | modifier le wikicode]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 :
try {
bloc_1
} catch(type_exception_1 arg_1) {
bloc_2
} catch(type_exception_2 arg_2) {
bloc_3
}...
} finally {
bloc_N
}
Si une erreur survient dans le bloc d'instructions no 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 no 1 exécuté sans erreur.
Depuis la version 7 de Java, il est possible d'utiliser le catch de multiple Exceptions :
try {
...
} catch(IOException|SQLException ex) {
.....
}
Un exemple continuant celui de l'introduction :
try {
Point p = new Point(u, v);
} catch(Exception e) {
System.out.println("Problème avec les coordonnées du point :");
System.out.println(e.getMessage());
e.printStackTrace();
}
À 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
[modifier | modifier le wikicode]- 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
[modifier | modifier le wikicode]Une exception peut être lancée via la syntaxe suivante :
throw exception;
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
[modifier | modifier le wikicode]On le peut en héritant de la class Exception
:
class CoordonneesIllegalesException extends Exception {
public CoordonneesIllegalesException () {
super("Coordonnées illégales.");
}
public CoordonneesIllegalesException (String msg) {
super(msg);
}
public CoordonneesIllegalesException (Throwable cause) {
super(cause);
}
public CoordonneesIllegalesException (String msg, Throwable cause) {
super(msg, cause);
}
}
Le constructeur de la classe Point de l’exemple introductif peut alors s'écrire :
public Point (int a, int b) throws CoordonneesIllegalesException {
if (a < 0 || a >= X_MAX || b < 0 || b >= Y_MAX) {
throw new CoordonneesIllegalesException();
}
x = a;
y = b;
}
Exceptions courantes
[modifier | modifier le wikicode]