MIM1
TD 4 de POOGL
Exception

Vincent BOUDET
Bureau 343 (84-70)
email vboudet@ens-lyon.fr

23 Janvier 2000

Ce TD est volontairement plus cours, afin de parler des projets en fin de s�ance.

A   Pourquoi g�rer les erreurs ?

En informatique, la gestion des erreurs est une pr�ocuupation majeure. On doit dsouvent g�rer des erreurs telles que la division par 0, l'acc�s � une zone m�moire interdite, etc. On doit se soucier des erreurs provoqu�es par le non-respect des proc�dures normales d'utilisation. On doit �galement prendre en compte l'apparition d'�v�nements inopin�s, comme un disque plein, une disquette non pr�sente, une erreur de frappe, etc. De plus, la gestion fine des erreurs facilite grandement la mise au point d'un programme.

Dans les langages structur�s classiques, il est habituel d'utiliser les valeurs retourn�es par les fonctions comme code d'erreur. La fonction appelante se charge alors de traiter les diff�rents cas d'erreur. Le code est alors particuli�rement peu lisible, car le deroulement du programme n'est pas sar� du traitement des erreurs.

B   Fonctionnement des exceptions

Java, comme beaucoup de langages r�cents, utilise les exceptions pour g�rer les erreurs ou les situations inhabituelles.Les exceptions sont des objets cr��s lors de situations d'erreurs et qui sont trait�s dans des sections r�serv�s � cet effet.

Concr�tement, quand le programme d�tecte une situation anormale ou une erreur il l�ve throw une exception. La lev�e d'une exception est n�cessairement inscrite dans un bloc d'essai (try), elle provoque instantan�ment la sortie du bloc concern� et doit �tre captur� dans un bloc catch

C   Exemple

import java.io.*;
public class LireDouble
{

  public static void main(String[] argv)
  {
    String ch;
    double x;
    BufferedReader fluxEntree;
    fluxEntree =  new BufferedReader(new InputStreamReader(System.in));
    try 
    {
      ch = fluxEntree.readLine();
      x = Double.valueOf(ch).doubleValue();
      System.out.println(``Double lu : `` +x);
    }
    catch (Exception e)
    {
      System.out.println(``Erreur de lecture d'un double:'' + e);
      System.exit(1);
    }
  }
}

D   Lever une exception

Dans le pragrahe pr�c�dent, l'exception avait �t� lev�e par une m�thode d'une classe de la biblioth�que Java, donc de fa�on invisible pour le programmeur. Pour lever soi m�me une exception on utilise l'instruction throw.
  throw newIllegalAccesError(``Acces interdit � la m�thode Toto.bidule()'');

E   Cr�er une classe d'exception

On peut cr�er des sous-classes de Exception ou d'une de ses sous-classes. Par exemple :
import java.io.*;
public class LectureErreur extends Exception
{
  LectureErreur()
  {}

  LectureErreur(String message)
  {
    super(message);
  }
}
On peut alors l'utiliser de la mani�re suivante :
import java.io.*;
public class ES
{
  public static void main(String[] argv) throws LectureErreur
  {
    String ch='''';
    BufferedReader fluxEntree;
    fluxEntree =  new BufferedReader(new InputStreamReader(System.in));
    try 
    {
      ch = fluxEntree.readLine();
      x = Double.valueOf(ch).doubleValue();
      System.out.println("Double lu : " +x);
    }
    catch (Exception e)
    {
      throw new LectureErreur(``Erreur de lecture d'un r�el double'');
    }
  }
}
La m�thode appelante va pouvoir traiter cette erreur en prenant en compte le contexte dans lequel elle est survenue. Pour qu'une m�thode puisse d�l�guer le traitement d'une exception � une m�thode appelante, elle doit le signaler par une clause throws dans son en-t�te. Pour qu'une exception soit control�e, il faut qu'elle soit d�clar�e par throws ou captur�e par catch.

F   Ajout de champ

L'utilisateur a parfois besoin de renseignements compl�mentaires. On aimerait par exemple savoir quelle chaine de caract�res a �t� lue.
import java.io.*;
public class LectureErreur extends Exception
{
  String chaineLue = null;
  LectureErreur()
  {}

  LectureErreur(String message)
  {
    super(message);
  }
  
  LectureErreur(String message, String chaine)
  {
    super(message);
    this.chaineLue=chaine;
  }

  String toString()
  {
    String ch;
    if (chaineLue != null )
    {
      ch = getMessage() + ``\n Chaine lue ayant provoqu�e l'erreur : ``;
      ch = ch + chaineLue;
    }
    else
      ch = getMeassge();
    return ch;
  }
}

G   Finally

L'instruction try ... catch peut comporter une clause finally qui sera execut�e dans tous les cas. Cette clause est peu utilis�e, elle sert g�n�ralement � fermer les flux ouverts dans des op�rations d'entr�es-sorties.

H   � vous

H.1   Tampon de nombres entiers

Cr�er une classe TamponEntiers qui contient un champ de type int[]. Il a une capacit� initiale communiqu�e en argument du constructeur. Quand le tableau est satur� (pensez aux exceptions), la m�thode agrandir() construit un nouveau tableau de capacit� sup�rieure. Cette classe devra comporter les m�thodes suivantes :

H.2   SaturationMemoireException

Cr�er une classe SaturationMemoireException �tendant la classe Exception. On la dotera d'un constructeur vide et d'un constructeur prenant une chaine comme argument afin de donner des pr�cisions sur la nature des circonstances ayant provoqu� la lev� de l'exception.

Les tampons TamponEntiers peuvent provoquer un arr�t brutal du programme lors de l' appel � la m�thode agrandir() quand la quantit� de m�moire disponible est insuffisante. Capturer l'erreur de type OutOfMemoryError qui peut survenir dans la m�thode agrandir() et lever alors une exception de type SaturationMemoireException. Elle sera propag�e jusqu'� la m�thode ajouter() afin que l'utilisateur ait la possibilit� d'imprimer le travail en cours. Tester cette nouvelle classe TamponEntier en ajoutant des nombres entiers jusqu'� provoquer la saturation de la m�moire.

H.3   La factorielle

�crire un programme simple qui calcule la factorielle d'un nombre donn� sur la ligne de commande.

� partir de ce programme simple, modifiez le en utilisant des classes d'exception pour rattraper les erreurs suivantes : Dans les deux premiers cas, une exception est signal�e. Dans les deux derniers cas, le r�sultat est faux.

Vous devez modifier le programme pour que, dans chacun de ces cas, l'erreur soit pr�cis�e � l'utilisateur. Dans le premier cas, on souhaite que le programme affiche par exemple : Indiquez le nombre d'entiers sur la ligne de commande et si le param�tre indiqu� est -4 :
-4 est n�gatif : la factorielle n'est pas d�finie. 

This document was translated from LATEX by HEVEA.