Les exceptions
Objectifs du chapitre
L’objectif de ce chapitre est d’appréhender les outils permettant de traiter les erreurs (exceptions) qui peuvent se produire au cours de l’exécution d’un programme.
Mécanisme des exceptions
1. Compréhension des messages
public class A
{
private int x, y, z;
public A(int a, int b)
{
x = a;
y = b;
z = x / y;
}
}
L’exécution de l’instruction z = x / y du constructeur de la classe A peut provoquer une erreur si la propriété y vaut 0 (zéro). Dans ce cas, la machine virtuelle instancie un objet de la classe ArithmeticException et interrompt l’exécution du constructeur.
Exemple
public class Exception01
{
public static void main(String argv[])
{
A a = new A(10, 0);
}
}
Voici le résultat de l’exécution de ce programme :
Les "at" du message d’erreur indiquent la pile des méthodes appelées.
L’erreur se produit dans l’exécution du constructeur (<init>) de la classe A, lui-même appelé dans la méthode main() de la classe Exception01. Entre parenthèses, figure le nom du fichier source avec le numéro de la ligne où se produit l’erreur : ligne 9 du constructeur, ligne 5 de la méthode main().
2. Exceptions surveillées, exceptions non surveillées
a. Exemple
Le programme suivant "cache" deux exceptions :
import utilitairesMG.divers.*;
public class SurveilleeNonSurveillee
{
public static void main(String argv[])
{
int nombre;
System.out.print("Saisir un nombre entier : ");
nombre = Clavier.readInt();
System.out.println("\nNombre saisi : " + nombre);
}
}
La plus mal "cachée" est détectée par le compilateur :
La méthode readInt() de la classe Clavier, est susceptible d’émettre une erreur de type IOException (package java.io). Cette erreur est une erreur surveillée. Le compilateur impose au programmeur de la traiter.
Dans le programme corrigé, ce traitement est fait...
Exemples d’utilisation des exceptions
1. Classe Fraction
Cette classe est utilisée dans tous les exemples de la section.
public class Fraction
{
private int numerateur;
private int denominateur;
public Fraction(int numerateur, int denominateur)
{
this.numerateur = numerateur;
this.denominateur = denominateur;
}
public int partieEntiere()
{
return numerateur / denominateur;
}
public String toString()
{
if (denominateur != 1)
{
return numerateur + " / " + denominateur;
}
else
{
return "" + numerateur;
}
}
}
La méthode partieEntiere() est susceptible de provoquer une ArithmeticException si le dénominateur vaut 0.
2. Saisie du numérateur et du dénominateur dans un bloc try
Chaque appel de la méthode readInt() de la classe Clavier peut émettre une NumberFormatException.
public class Exemple1
{
public static void main(String argv[]) throws IOException
{
...
Création et lancement d’une exception
Toutes les exceptions des exemples précédents ont été créées par la machine virtuelle.
Créer une exception, c’est instancier un objet d’une classe qui hérite de la classe Exception.
Pour que l’exception puisse être attrapée (catch), il faut qu’elle soit lancée (throw). C’est le rôle du mot-clé throw.
L’instruction throw new TypeException(); lance une exception de type TypeException.
L’exception qui vient d’être créée et lancée par le programmeur peut maintenant être traitée comme toute exception, par un catch ou un throws.
Création d’une nouvelle classe d’exception
Une classe d’exception est une classe qui hérite de la classe Exception.
Exemple
public class DenominateurNulException extends Exception
{
public DenominateurNulException()
{
super("Le denominateur est nul !");
}
}
On souhaite empêcher l’instanciation d’une Fraction dont le dénominateur vaut 0. Il est possible de modifier le constructeur de Fraction :
public class Fraction
{
. . .
public Fraction(int numerateur, int denominateur)
throws DenominateurNulException
{
if (denominateur == 0)
{
throw new DenominateurNulException();
}
this.numerateur = numerateur;
this.denominateur = denominateur;
}
. . .
}
Quand le dénominateur vaut 0, le constructeur lance une exception :
throw new DenominateurNulException();
Le constructeur décide de remonter cette erreur au programme appelant :
throws DenominateurNulException
Le programme appelant subit...
Travail pratique : saisies d’entiers
1. Sujet
La méthode readInt() de la classe Clavier (package utilitairesMG.divers) produit deux sortes d’exceptions :
-
Une exception surveillée IOException.
-
Une exception non surveillée NumberFormatException qui se produit en cas de saisie incorrecte.
Travail à effectuer :
-
Écrire une classe ClavierInt comportant une méthode readInt(int min, int max). Cette méthode renvoie, en plus des deux erreurs ci-dessus, une erreur de type BorneException si la valeur saisie n’est pas comprise entre les bornes min et max.
-
Écrire une classe ControleInt, comportant une méthode saisieInt(int min, int max) effectuant la saisie d’un entier en boucle jusqu’à ce que la saisie soit correcte.
Programme de test de ControleInt :
import java.io.*;
public class TestControleInt
{
public static void main(String argv[]) throws IOException
{
int i;
i = ControleInt.saisieInt(150, 200);
System.out.println("Valeur saisie : " + i);
}
}
Voici un exemple de résultat d’exécution de ce programme :
2. Saisies d’entiers : proposition de correction
a. Classe BorneException
La classe BorneException hérite de Exception. C’est une exception surveillée.
Le constructeur de BorneException appelle celui d’Exception en lui transmettant une chaîne constituée à partir de trois paramètres :
-
valeur : entier en erreur ;
-
min : borne inférieure ;
-
max : borne supérieure.
Le message...