1)Introduction Java

publicité
TSIG2 DA
DAIGL S36
Cours n°1
3ème partie
5. Le traitement des erreurs (exceptions)
Java prévoit un mécanisme pour le traitement des anomalies qui peuvent survenir lors de
l'exécution du programme.
C'est ce qu'on appelle le traitement des exceptions.
Les exceptions peuvent être des erreurs graves qui devront généralement conduire à l'arrêt du
programme ou des événements qui seront traités de sorte qu'ils ne provoquent pas l'arrêt du
programme, par exemple : erreur de format de donnée, division par zéro, dépassement
d’indice dans un tableau ou une chaîne …
5.1. Le renvoi des exceptions
Si une exception n'est pas traitée dans la méthode dans laquelle elle survient, il faut qu’elle
soit renvoyée à la méthode du niveau immédiatement supérieur et ainsi de suite jusqu’à ce
qu’une méthode la traite.
Enfin si l'exception sort de la méthode main non encore traitée, elle est alors traitée par la
machine virtuelle Java.
Le renvoi (ou l’outrepassement) des exceptions se fait explicitement en indiquant throws
TypeException dans l’en-tête de la méthode (exemple : public void saisie throws
IOException) ou bien implicitement pour les exceptions les plus courantes (ces dernières sont
effectivement renvoyées à la méthode appelante si elles ne sont pas traitées dans la méthode
qui les voit naître, sans que le programmeur n’ait à préciser quoi que ce soit).
5.2.La capture des exceptions
Pour cela, Java introduit des mot-clés spéciaux que nous allons aborder ci-dessous.
Le mot-clé try indique que le code qui suit est susceptible de générer une exception.
L'interception de cette exception se fera par le mot-clé catch et l'action correspondante sera
codée immédiatement après le mot-clé catch.
La syntaxe est la suivante :
try
{
// bloc de code pouvant générer l'exception
}
catch (TypeException e)
{
// traitement approprié
}
catch (TypeException e)
{
1
TSIG2 DA
DAIGL S36
Cours n°1
3ème partie
...
}
// Le bloc finally est facultatif. Il est exécuté dans tous les cas et en dernier. En fait, il sera
// rarement présent, on le code par exemple pour la fermeture des fichiers.
finally
{
...
}
Chacune des instructions try, catch et finally doit être suivie d'un bloc { ... } même si ce bloc
ne comporte qu'une seule instruction.
Si une exception est générée dans les instructions du bloc try, elle est alors interceptée par le
bloc catch correspondant (on sait qu'un catch est destiné à capturer un certain type
d'exception d'après la classe de l'exception mentionnée après ce catch) s'il existe.
Si on souhaite que catch capture n’importe quelle exception, on indique Exception comme
type d’exception  catch (Exception e)
Exemple : calcul de la factorielle
import java.io.*;
class Factorielle
{
public static void main(String args[]) throws IOException
{
BufferedReader rep = new BufferedReader(new
InputStreamReader(System.in));
int nombre, res = 1;
System.out.println("Saisir le nombre dont il faut calculer la factorielle");
do
{
try
{
nombre = Integer.parseInt(rep.readLine());
}
catch (NumberFormatException e)
{
nombre = -1;
}
}
while (nombre < 0 || nombre > 10);
for (int i=2; i<=nombre; i++)
res *= i;
System.out.println("Factorielle = " + res);
}
}
2
TSIG2 DA
DAIGL S36
Cours n°1
3ème partie
Exemple : calcul de la moyenne d’une liste d’entiers transmis en paramètres
class Essaiexceptions
{
public static void main(String[] argv)
{
try
{
System.out. println("La moyenne est " + moyenne(argv));
}
catch (ArithmeticException e)
{
System.out. println("Paramètres absents ou tous incorrects");
}
}
// Le throws ArithmeticException est facultatif car comme il s’agit d’une erreur
// considérée comme courante, elle est renvoyée implicitement à la méthode appelante
// si elle n’a pas été traitée dans la méthode qui l’a vue survenir.
static int moyenne(String[] liste) throws ArithmeticException
{
int somme = 0, entier, nbNotes = 0;
for (int i = 0; i < liste.length;i++)
{
try
{
entier = Integer.parseInt(liste[i]);
somme += entier;
nbNotes++;
}
catch (NumberFormatException e)
{
System.out.println("La note numero "+(i+1)+
" n'est pas entiere");
}
}
return somme/nbNotes;
}
}
Déclaration d'exceptions
Avant de voir comment déclarer une exception dans une méthode, il faut savoir comment
lancer une exception. Prenons l'exemple suivant:
3
TSIG2 DA
DAIGL S36
Cours n°1
3ème partie
// DiviseParZero.java
class DiviseParZero
{
public static void main (String args[])
{
int zero=0;
try
{
zero = 2002/zero;
}
catch (ArithmeticException e )
{
System.out.println("Une exception arithmetique a ete lancee");
System.out.println("Message : " + e.getMessage());
System.out.println("Pile :");
e.printStackTrace();
}
}
}
Java utilise pour lancer une exceptions le mot clé throw. Par exemple, si nous ajoutons dans
notre programme la ligne suivante juste avant le calcul provoquant l'exception arithmétique
(dans le bloc try):
if (zero==0 )
throw new ArithmeticException ("Division par zero");
On obtient :
Une exception arithmétique a été lancée
Message : Division par zéro
Pile :
java.lang.ArithmeticException: Division par zéro
at DiviseParZero.main(DiviseParZero.java:8)
Cette fois-ci, nous avons nous même lancé cette exception, en indiquant un message précisant
la nature exacte de l'erreur, redéfinissant l'exception par défaut.
5.3.Définir ses propres exceptions (compléments à revoir après cours sur
l’héritage)
Il est possible de définir sa propre exception. Pour ce faire, il suffit de définir sa classe
exception, qui devra dériver de la classe Exception. Ensuite, nous allons créer une fonction
qui va lever notre exception. Pour ce faire, il est obligatoire de préciser dans la signature de la
fonction la liste des exceptions susceptibles d'être lancées. Voici le source de notre exemple :
4
TSIG2 DA
DAIGL S36
Cours n°1
3ème partie
// CreeException.java
class NouvelleException extends Exception
{
NouvelleException () {}
NouvelleException (String msg)
{
super(msg);
}
}
public class CreeException
{
static void fnct () throws NouvelleException
{
// On lance l'exception
throw new NouvelleException ("Exception nouvelle lancee");
}
public static void main (String argv[])
{
try
{
// On appelle la fonction qui lance l'exception
fnct();
}
catch (NouvelleException e)
{
// On attrape cette exception
e.printStackTrace();
}
}
}
Analysons cet exemple. Tout d'abord, nous déclarons notre nouvelle exception en créant une
classe dédiée, héritée de la classe Exception. On crée deux constructeurs, l'un sans argument
qui ne fait rien, l'autre prenant un message en argument. Ce message est transmis au
constructeur de la classe parente, grâce au mot clé super() que nous avons vu plus haut.
Ensuite, nous définissons une classe, dans laquelle on crée une méthode qui lance l'exception
que nous venons de définir. Comme nous l'avons dit précédemment, on spécifie quelles
exceptions peuvent être lancées dans la signature de la fonction, soit ici:
static void fnct () throws NouvelleException {
Cette fonction se contente de lever l'exception NouvelleException.
Enfin, dans la méthode main(), nous faisons appel à la fonction précédente en installant un
gestionnaire d'exceptions. Le bloc catch() attrape notre exception et affiche à l'écran le
contenu de la pile d'appel des fonctions :
NouvelleException: Exception nouvelle lancee
at CreeException.fnct(CreeException.java:14)
at CreeException.main(CreeException.java:20)
5
TSIG2 DA
DAIGL S36
Cours n°1
3ème partie
Remarquons que notre message spécifié lors de la lancée de l'exception a été reproduit.
On note également que la pile d'appel contient deux fonctions, celle dans laquelle on lève
l'exception, et celle appelant cette dernière, avec indication des numéros de lignes respectifs
Annexe- Le tableau suivant propose quelques exemples d'exceptions que l’on peut
traiter.
SQLException
erreurs SQL
IOException
erreurs d’entrées/sorties
NullPointerException
adresse nulle
OutOfMemoryException
adresse invalide
ArithmeticException
erreur sur opération
ArrayIndexOutOfBoundsException Sortie du tableau
ArrayStoreException
Element incompatible
negativeArraySizeException
taille négative pour un tableau
6
Téléchargement