Exceptions
1) Exemple sans exception
public double get( int i ) { return tab[i-1]; }
que retourner si mauvais indice ?
2) Définition
2.1. Une exception est un évènement exceptionnel
qui peut survenir pendant le déroulement d'un programme
et qui provoque le déroutement du flot d'instructions normal.
2.2. En java, une exception est un objet d'une sous-classe d'Exception
et des exceptions de types différents peuvent être distinguées.
2.3. On peut créer ses propres exceptions et y ajouter de l'information.
3) Système de gestion des exceptions
3.1. "parallèle" au déroulement normal;
lancer une exception et la rattraper ailleurs
3.2. Exemple
main()
{
...
procA();
...
...
...
...
...
}
|
void procA()
{
...
procB();
./.
|
ttt exception
|
...
...
}
|
void procB()
{
...
...
double d=get(11);
./.
./.
./.
./.
}
|
double get(final int i)
{
...
...
...
EXCEPTION!
./.
./.
return valeur;
}
|
get() lance une exception
(donc instructions suivantes non exécutées)
--> procB( )
procB() n'a rien prévu pour la traiter
(donc propage l'exception)
(donc instructions suivantes non exécutées)
--> procA( )
procA() sait traiter
l'exception et continue son exécution
après le traitement de l'exception
(mais quelques instructions non exécutées quand-même)
main() ne s'est aperçu de rien
si rien n'est prévu nulle part, le programme se termine
avec un long message (StackTrace).
4) Avantages
4.1. séparer les instructions normales du traitement des erreurs
4.2. propager l'exception à la méthode appelante et ainsi de suite
4.3. différencier et regrouper des exceptions différentes grâce
aux hiérarchies de classes (héritant de Exception)
5) Exceptions existant dans Java
5.1. Hiérarchie
Object
^
Throwable
^ ^
Error Exception
| | | | | | | ^
| | | | RuntimeException
| | | | | | | | |
1 2 3 .. 4 5 6 7 ..
5.2. Error est un type d'erreur système "grave"; on ne peut rien faire,
donc inutile d'essayer de les attraper et traiter.
(exemples: AssertionEr, VirtualMachineEr, OutOfMemoryEr, StackOverflowEr)
5.3. Exception est un type d'erreur qui peut être traitée; on a le choix
de dire qu'une méthode la lance ou bien de l'attraper et traiter
à l'intérieur.
(catch or specify, checked exceptions, outside JVM)
(exemples: CloneNotSupportedEx, AWTEx, IOEx, EOFEx, FileNotFoundEx)
5.4. RuntimeException est un type particulier d'exception qui correspond
en général à une erreur du programmeur; on n'a donc pas obligation
ni de la déclarer ni de l'attraper et traiter.
Par contre, on a obligation de corriger son programme pour qu'elle n'arrive pas !
(unchecked exceptions, inside JVM)
(exemples: ArithmeticEx, ClassCastEx, NegativeArraySizeEx, NullPointerEx,
IllegalArgumentEx, NumberFormatEx, IndexOutOfBoundsEx)
5.5. Les classes 1 2 ... correspondent aux exceptions déjà définies dans les
nombreuses classes Java.
6) Traitement des exceptions lancées par le JDK
6.1. Exemple:
try { instructions }
catch ( UneClasseException pObjetException ) { traitement }
(voir méthodes getStackTrace(), printStackTrace(), getMessage(),
getLocalizedMessage(), toString())
6.2. S'il y a plusieurs exceptions possibles, on peut mettre
successivement plusieurs catch après un seul try.
Attention! l'ordre est important (du particulier au général)
6.3. Si un traitement est commun à plusieurs exceptions héritant
d'une même classe, écrire
catch ( ClasseMereException objetException )
6.4. On sait quelle classe exception en regardant la javadoc
Exemple: Throws: UneClasseException
6.5. Si une méthode appelée lance une exception dont la classe
n'hérite pas de
RunTimeException,
soit il faut entourer l'appel d'un
try/catch,
soit il faut déclarer qu'on lance l'exception
==> throws UneClasseException
à la fin de la signature (plusieurs possibles)
6.6. On peut traiter partiellement et relancer l'exception
dans le
catch:
throw e;
==> throws UneClasseException
6.7. Si un traitement doit être fait qu'une exception soit lancée
ou pas, ajouter après le
try/catch un bloc
finally { traitement }
7) Lancer des exceptions du JDK
7.1. Exemple:
if (mauvais paramètre) throw new UneClasseException("...");
==> throws UneClasseException
7.2. Ne pas rattraper une exception dans la même méthode que celle
où on l'a lancée; il vaut mieux
if (cond) { i1 } else { i2 }
que
try { if (!cond) throw new UneClasseException(); i1 }
catch ( UneClasseException e ) { i2 }
8) Créer ses propres exceptions
8.1. Créer une classe qui extends Exception ou une de ses sous-classes
8.2. Redéfinir éventuellement getMessage()
8.3. Ajouter éventuellement des attributs (donc constructeur),
voire des méthodes
9) Les assertions
9.1. Programmation par contrat, sécurité :
pré-condition, post-condition, pas d'invariant
9.2.
assert condition : message;
équivalent à
if (!condition) throw new AssertionError(message);
mais comment les retirer ?
9.3. Pour autoriser les assertions :
-ea à la compilation (difficile en BlueJ,
voir javac)