1
Gestion des exceptions
E/S
Problèmes des erreurs dans les programmes
2
erreur matérielle (imprimante débranchée, serveur en
panne),
contrainte physique (disque plein),
erreurs de programmation (cas non prévu par le
programme, division par zéro, ouverture d’un fichier
qui n’existe pas),
utilisateur récalcitrant (type de données rentrées par
l’utilisateur incorrect)
En cas de problèmes
3
envoyer un message d’erreur,
sauvegarder l’ensemble du travail en cours,
permettre une sortie correcte du programme,
revenir en arrière et effectuer un autre traitement.
Comment faire
4
Solution : tout prévoir (tester l’égalité à zéro du
dénominateur avant une division, etc.)
Problème : vous avez beau être un bon
programmeur vous ne pouvez pas tout contrôler
que faire dans le cas d’un mauvais type en entrée, ou
pour les cas non prévus par le programme ?
Exceptions
5
2 familles d’exceptions:
non fatales
fatales (provoquent l’arrêt du programme).
Hiérarchie des exceptions
6
Object
Throwable
Exception
Error
RunTimeException IOException
…
7
Une exception est un objet de type Exception
Instancier par n’importe quelle sous-classe d’Exception
Hiérarchie RuntimeException et Error
Unehiérarchie d’exceptions non contrôlées par le
compilateur
Hiérarchie error: erreurs graves
8
Exemples
NoSuchMethodError: la méthode référencée n’est pas
accessible
StackOverflowError: débordement de pile
Hiérarchie RuntimeException
9
Exemples
ArithmeticException: une erreur arithmétique (division
par 0…)
IndexOutofBoundsException: indice d’un tableau est en
dehors des bornes autorisées.
Il n’est pas obligatoire de gérer les exceptions de
type RuntimeException
10
public class ZeroDivide
{
static public void main(String[] args)
{
int a = 3;
int b = 0;
[Link]("Resultat de la division : " + a/b);
}
}
Ce code se compile mais une exception apparaît au niveau de l’exécution et
le programme s’arête.
Une ArithmeticException est une RuntimeException.
Les RuntimeException ne sont pas vérifiées par le compilateur
Les autres exceptions doivent être prise
11
en compte
public class TaperTouche
{
static public void main(String[] args)
{
[Link]("Tapez une touche pour terminer le programme");
[Link]();
}
}
Ce code ne compile pas parce que la méthode read() est
susceptible de lever une exception de type IOException
12
L’appel d’une méthode qui lance une exception (une
méthode qui déclare qu’elle lance une exception)
doit être pris en compte dans le code appelant
Encapsuler l’appel dans un bloc try/catch
Contrôle de flot dans les blocs
13
Try/catch
Try { Si le bloc Try réussit
1 Instruction 1; //dans cette instruction il y a une possibilité de levée d’exception
Instruction i ;
} catch (Exception ex) {
Instruction j;
}
2 Instruction k;
Contrôle de flot dans les bloc
14
Try/catch
Try { Si le bloc Try échoue
1 Instruction 1; // dans cette instruction il y a une possibilité de levée d’exception
Instruction i
} catch (Exception ex) {
2 Instruction j;
}
3 Instruction k;
Finally pour ce qui s’exécute dans tous
15
les cas
Try { Try {
Instruction 1; Instruction 1;
Instruction i; Instruction i;
} catch (Exception ex) { Instruction k;
Instruction j; } catch (Exception ex) {
} finally { Instruction j;
Instruction k; Instruction k;
} }
Remarque: si le bloc try/catch a une instruction return finally s’exécute quand même
Le flot saute à finally puis revient à return
Extrait de la documentation de la
16
classe read
Method Detail read
public abstract int read() throws IOException
Reads the next byte of data from the input stream. The value byte is
returned as an int in the range 0 to 255. If no byte is available because
the end of the stream has been reached, the value -1 is returned. This
method blocks until input data is available, the end of the stream is
detected, or an exception is thrown. A subclass must provide an
implementation of this method.
Returns:
the next byte of data, or -1 if the end of the stream is reached.
Throws:
IOException - if an I/O error occurs.
Deux manières de gérer les exceptions:
la prendre en compte ou l’esquiver
17
import [Link];
public class TaperTouche
{
static public void main(String[] args)
{
[Link]("Tapez une touche pour terminer le programme");
try
{
[Link]();
}
catch(IOException e)
{
[Link]("Une IOException a été détecté !");
}
}
}
L’esquiver
18 Il s’agit de déclarer que vous lancez l’exception même si
techniquement ce n’est pas vous qui la lancez
public class TaperTouche
{
static public void main(String[] args) throws IOException
{
[Link]("Tapez une touche pour terminer le programme");
[Link]();
}
}
19
public class TaperTouche
{
static public void LireClavier() throws IOException {
[Link]("Tapez une touche pour terminer le programme");
[Link]();
}
}
Public class Main {
static public void main(String[] args) throws IOException
{
[Link]();
}
Si Main n’esquive pas l’exception ou ne l’encapsule pas
dans un bloc try/catch il y a une erreur de compilation.
Une RunTime exception peut être
également intercepter et déclarer
20
public class ZeroDivide
{
static public void main(String[] args)
{
int a = 3; int b = 0;
try
{
[Link]("Resultat de la division : " + a/b);
[Link]("Instructions suivant la division...");
}
catch(ArithmeticException e)
{
[Link]("Une exception s’est produite ! (ArithmeticException)");
}
[Link]("Instructions qui suivent le bloc catch...");
}
}
Maintenant, la division par zéro ne provoque pas la terminaison du programme.
Créer ses propres classes d’exception
21
Imposer à la classe de dériver de la classe
standard Exception
Exemple transmission d’un message au gestionnaire d’exception
sous forme d’une information de type chaîne.
La classe Exception dispose d’un constructeur à un argument
de type String dont on peut récupérer la valeur à l’aide de la
méthode getMessage.
class MonZeroException extends Exception
{
public MonZeroException(String e){
super(e);
22 }
}
public class laClauseThrows {
public static void main (String[] args){
try{
[Link]("je verifie le nombre donne en argument.");
[Link](args);
}
catch (MonZeroException e){
[Link]([Link]()); // getMessage méthode de la classe Throwable
// [Link](); méthode de la classe Throwable affiche l’état de la pile d’appels
}
}
public static void test(String [] args) throws MonZeroException {
int n=[Link](args[0]);
if (n==0) throw new MonZeroException("j’ai vu un zero");
[Link]("il n’y a pas eu d’exception pour zero");
}
}
}
Exemple transmission d’information au constructeur de
l’objet exception
23
class Point { public class Exoinfo1 {
private int x,y; public static void main (String args[]) {
public Point(int a, int b) throws ErrConst try {
{ Point a = new Point (1,4);
if ((a<0) || (b<0)) throw new ErrConst(a,b); [Link]();
this.x =a; this.y=b; a = new Point (-3,5);
} [Link]();
public void affiche() { }
[Link]("Coordonnées:" +x+" "+y); catch (ErrConst e)
} {
}
class ErrConst extends Exception { [Link]("Erreur construction point");
[Link]("coordonnees souhaitées"+[Link]+" "+[Link]);
public int abs;
[Link](-1);
public int ord;
}
ErrConst (int abs, int ord) {
}
[Link] = abs; [Link]=ord;
}
}
} }
Exercice
public class TestExceptions { 24
public static void main (String [] args) {
String test = "non";
try {
[Link]("Début de try");
prendreRisque(test);
[Link]("Fin de try");
} catch (HorribleException he) {
[Link]("Horrible exception"); }
finally {
[Link]("finally");
}
[Link]("fin de main");
}
static void prendreRisque(String test) throws HorribleExeception {
[Link]("début de risque");
if ("oui".equals(test)) {
throw new HorribleException();
}
[Link]("fin de risque");
return;
}
}
Quel est le résultat quand test vaut « non » et quand test vaut « oui »?
Gérer plusieurs types d’exceptions
25
public class plusieursCatchs {
public static void main (String[] args){
Les blocs catch doivent être
ordonnés du plus petit au plus
try{ grand
[Link]("je verifie le nombre donne en argument.");
Cela dépend de la
int n=[Link](args[0]); hiérarchie d’héritage
if (n==0) throw new ZeroException("");
if (n>0) throw new SupAZeroException("");
if (n<0) throw new InfAZeroException("");
}
catch (ZeroException e){
[Link]("le nombre etait nul");
}
catch (SupAZeroException e){
[Link]("le nombre etait superieur a zero");
}
catch (InfAZeroException e){
[Link]("le nombre etait inferieur a zero");
}
}
}
Gérer plusieurs types d’exceptions
26
public class ZeroException extends Exception {}
public class SupAZeroException extends Exception {}
public class InfAZeroException extends Exception {}
Conclusion
27
La gestion des exceptions permet de dissocier le programme
principal de la gestion des erreurs, ou des arrêts brusques
du programme.
Ce n’est pas une nouvelle structure de contrôle en plus des if,
while, for, switch.
La gestion des erreurs ralentit considérablement la vitesse du
programme
Les exceptions doivent rester exceptionnelles!