Vous êtes sur la page 1sur 25

Gestion des exceptions - Gestion des entrées et des sorties

Programmation Orientée Objet en JAVA


Module: M22 - 4ième Année FI-GTR

Pr. Abdessamad EL BOUSHAKI


abdessamad.elboushaki@gmail.com

ENSA de Fès
Université Sidi Mohammed Ben Abdellah

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Gestion des exceptions

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 2
Gestion des exceptions - Gestion des entrées et des sorties

Définition

Lors de l’écriture d’un programme, la prise en compte d’erreurs prend une


place très importante si l’on souhaite écrire un programme robuste.
Par exemple, la simple ouverture d’un fichier peut provoquer beaucoup
d’erreurs telles que l’inexistence du fichier, un mauvais format, une
interdiction d’accès, une erreur de connexion au périphérique, ...
Pour que le programme soit robuste, il faut que toutes les erreurs
possibles soient détectées et traitées.
Certains langages de programmation, dont le langage Java, proposent un
mécanisme de prise en compte des erreurs, fondé sur la notion d’exception.
Une exception est un objet qui peut être émis par une méthode si un
événement d’ordre exceptionnel (les erreurs rentrent dans cette catégorie)
se produit.
La méthode en question ne renvoie alors pas de valeur de retour, mais émet
une exception expliquant la cause de cette émission.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 3
Gestion des exceptions - Gestion des entrées et des sorties

Définition

La gestion d’erreurs par propagation d’exception présente deux atouts


majeurs :

I Une facilité de programmation et de lisibilité : il est possible de regrouper


la gestion d’erreurs à un même niveau. Cela évite des redondances dans
l’écriture de traitements d’erreurs et encombre peu le reste du code avec ces
traitements.

I Une gestion des erreurs propre et explicite : certains langages de


programmation utilisent la valeur de retour des méthodes pour signaler une
erreur à la méthode appelante. Etant donné que ce n’est pas le rôle de la
valeur de retour de décrire une erreur, il est souvent impossible de connaı̂tre
les causes réelles de l’erreur. La dissociation de la valeur de retour et de
l’exception permet à cette dernière de décrire précisément la ligne de code
ayant provoqué l’erreur et la nature de cette erreur.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 4
Gestion des exceptions - Gestion des entrées et des sorties

Classification des erreurs en Java


On peut distinguer quatre types de situations d’erreurs en Java :
I Erreurs de compilation. Avant même de pouvoir exécuter le programme,
notre code source génère des erreur par le compilateur. Il faut alors réviser et
corriger le code pour ne plus avoir d’erreurs.
I Erreurs d’exécution. Alors que notre programme est en cours d’exécution, la
JVM étant mal configurée ou corrompue, le programme s’arrête ou se gèle. A
priori, c’est une erreur non pas due à notre programme, mais à la
configuration ou l’état de l’environnement d’exécution de notre programme.
I Exception non vérifiée. Alors que notre programme est en cours d’exécution,
une trace de la pile des exceptions est affichée, pointant vers une partie de
notre code sans gestion d’exception. Visiblement, nous avons utilisé du code
qui est capable de lever un exception non vérifiée (comme
NullPointerException). Il faut modifier le programme pour que cette
situation ne survienne pas.
I Exception vérifiée. Une trace de la pile des exceptions est affichée, pointant
vers une partie de notre code avec gestion d’exception. Visiblement, nous
avons produit du code qui est capable de lever un exception vérifiée (comme
FileNotFoundException) mais les données passées à notre programme ne
valide pas ces exceptions. Il faut alors revoir les données passées en paramètre
du programme.
Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 5
Gestion des exceptions - Gestion des entrées et des sorties

Hiérarchie des exceptions

Une classe est considérée comme une classe d’exception dès lors qu’elle
hérite de la classe Throwable.
Un grand nombre de classes d’exception sont proposées dans l’API pour
couvrir les catégories d’erreurs les plus fréquentes.
Elles constituent un arbre hiérarchique utilisant la notion d’héritage.

Object // la classe racine de toutes les classes


Throwable // la classe m è re de toutes les exceptions
Error // erreurs graves , abandon du programme
Exception // anomalies r é cup é rables
Ru n T i m e E xception // erreur à l ’ ex é cution
A r i t h m e t i c E x c e p t io n // division par z é ro par exemple
C l a s s C a s t Ex c ep ti o n // mauvaise conversion de classes ( cast )
IndexOutOfBoundsException // en dehors des limites ( tableau )
NullPointerException // r é f é rence nulle
IllegalArgumentException // transmission inappropri é d ’ argument
NumberFormatException // nombre mal form é
IOException // erreurs d ’ entr é es - sorties
FileNotFoundException // fichier inconnu

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 6
Gestion des exceptions - Gestion des entrées et des sorties

Déclaration des exceptions


Il est nécessaire de déclarer, pour chaque méthode, les classes d’exception
qu’elle est susceptible d’émettre.
Cette déclaration se fait à la fin de la signature d’une méthode par le mot-clé
throws, à la suite duquel les classes d’exceptions (séparées par une virgule
s’il en existe plusieurs) qui peuvent être générées sont précisées.
Une méthode avec une propriété throws peut lancer des exceptions avec
throw :
public class ExempleExcepti o n
{
public static String month ( int mois ) throws I n d e x O u t O f B o u n d s E x c e p t i o n
{
if (( mois < 1) || ( mois > 12))
{
throw new I n d e x O u t O f B o u n d s E x c e p t i o n ( " le numero du mois qui est "
+ mois + " doit ^ e tre compris entre 1 et 12 " );
}
if ( mois == 1) return " Janvier " ;
else if ( mois == 2) return " F é vrier " ;
...
else if ( mois == 11) return " Novembre " ;
else return " D é cembre " ;
}
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 7
Gestion des exceptions - Gestion des entrées et des sorties

Déclaration des exceptions

En cas de nécessité, on peut créer de nouvelles classes d’exceptions et les


lancer avec throw. Elles descendent des classes Exception ou
RunTimeException mais pas de la classe Error.

class MyException extends Exception


{
MyException ( String msg )
{
System . out . println ( " MyException lancee , msg = " + msg );
}
}

void someMethod ( boolean flag ) throws MyException


{
if (! flag )
throw new MyException ( " no flag " );
...
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 8
Gestion des exceptions - Gestion des entrées et des sorties

Interception et traitement des exceptions

L’interception d’exceptions se fait par une sorte de ”mise sur écoute” d’une
portion de code. Pour cela on utilise le mot-clé try suivi du bloc à surveiller.
I Si aucune exception ne se produit dans le bloc correspondant, le programme
se déroule normalement comme si l’instruction try était absente.
I Par contre, si une exception est levée, le traitement de l’exception est exécuté
puis l’exécution du programme reprend son cours après le bloc testé.
Il est également nécessaire de préciser quelles classes d’exception doivent être
interceptées dans le bloc testé.
L’interception d’une classe d’exception s’écrit grâce au mot-clé catch suivi
de la classe concerné, d’un nom de variable correspondant à l’objet
exception, puis du traitement.
La clause finally définit un bloc qui sera toujours exécuté, qu’une
exception soit levée ou non. Ce bloc est facultatif. Il est aussi exécuté si
dans le bloc try il y a une instruction break ou continue.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 9
Gestion des exceptions - Gestion des entrées et des sorties

Interception et traitement des exceptions

Interception par bloc try - catch - finally

try
{
// quelques actions p ot en t ie ll em e nt risqu é es
}
catch ( SomeException se )
{
// que faire si une exception de ce type survient
}
catch ( Exception e )
{
// que faire si une exception d ’ un autre type survient
}
finally
{
// toujours faire ceci , quelle que soit l ’ exception
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Interception et traitement des exceptions

Dans l’exemple ci-dessous, le programme demande à l’utilisateur de saisir le


numéro d’un mois et affiche à l’écran le nom de ce mois. Les exceptions qui
peuvent être levées par ce programme sont traitées.

public class E x e m p l e T r a i t e m e n t E x c e p t i o n {
public static void main ( String [] args ) {
System . out . println ( " Entrez le numero d ’ un mois : " );
try {
Scanner input = new Scanner ( System . in );
int numero = input . nextInt ();
System . out . println ( E x e m p l e E x c e p t i o n . month ( numero ));
} catch ( I n d e x O u t O f B o u n d s E x c e p t i o n e ) {
System . err . println ( " Numero incorrect : " + e . getMessage ());
} catch ( I n p u t M i s m a t c h E x c e p t i o n e ) {
System . err . println ( " Entr é e incorrecte : " + e . getMessage ());
} catch ( IOException e ) {
System . err . println ( " Erreur d ’ acc è s : " + e . getMessage ());
}
}
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Interception et traitement des exceptions

Trois classes d’exception sont traitées dans cet exemple :


I IndexOutOfBoundsException (levé par la méthode month) se produit si le
numero entré par l’utilisateur est inférieur à 1 ou supérieur à 12 ;

I InputMismatchException (levé par la méthode nextInt) qui se produit si le


texte entré par l’utilisateur n’est pas convertible en entier ;

I IOException (levé par la méthode nextInt) qui se produit si il y a eu une


erreur d’accès au périphérique d’entrée.

Dans chacun de ces cas, le traitement consiste à afficher le message d’erreur


associé à l’exception.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Le choix entre throws et catch

Si on appelle une méthode qui lève une exception non runtime, on utilise :

I catch si l’on peut reprendre sur l’erreur et faire quelque chose de cohérent
(appliquer une action corrective).

I Sinon throws pour propager l’exception vers celui qui a appelé la méthode qui
fera ce qu’il doit faire.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Gestion des entrées et des sorties

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Définition

Une entrée/sortie en Java consiste en un échange de données entre le


programme et une autre source, par exemple la mémoire, un fichier, le
programme lui-même ...

Le package java.io propose un ensemble de classes permettant de gérer la


plupart des entrées/sorties d’un programme.

Cette gestion consiste à créer un objet flux dans lequel transitent les données
à envoyer ou à recevoir.

Celui-ci joue le rôle de médiateur entre la source des données et sa


destination.

Toute opération sur les entrées/sorties doit suivre le schéma suivant :


ouverture du flux, lecture/Ecriture de données, fermeture du flux.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Flux d’entrée

Un flux d’entrée est une instance d’une sous-classe de InputStream.


Chaque classe de flux d’entrée a son propre mode d’échange de données qui
spécifie un format particulier de données ou un accès particulier. Les classes
les plus couramment utilisées sont :
I ByteArrayInputStream permet de lire le flux d’entrée sous la forme d’octets
(byte).
I DataInputStream permet de lire le flux d’entrée sous la forme de types de
données primitifs de Java. Il existe des méthodes pour récupérer un entier, un
réel, un caractère,...
I FileInputStream est utilisé pour lire le contenu d’un fichier.
I ObjectInputStream permet de lire des objets (c-à-d des instances de classes
Java) à partir du flux d’entrée, si ces objets implémentent les interfaces
java.io.Serializable ou java.io.Externalizable.
I Reader n’est pas une sous-classe de InputStream mais représente un flux
d’entrée pour chaı̂nes de caractères.
I Scanner n’est pas une sous-classe de InputStream, mais un Iterator qui
permet de lire un flux ”mot” par ”mot” en définissant le délimiteur entre les
mots (espace par défaut).

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Flux d’entrée - Lecture des entrées clavier


Les données provenant de l’utilisation du clavier sont transmises dans un flux
d’entrée créé automatiquement pour toute application Java.
On accède à ce flux par la variable statique de la classe java.lang.System
qui s’appelle in. Ce flux est alors utilisé comme paramètre d’entrée du
constructeur d’un autre flux d’entrée.
Pour cet autre flux, on utilise généralement une sous-classe de Reader pour
récupérer les entrées de l’utilisateur sous la forme d’une chaı̂ne de caractères.
La classe Clavier en donne un exemple

import java . io .* ;
public class Clavier {
public static void main ( String [] args ) {
try {
BufferedReader flux = new Buffe redReade r (
new I n p u t S t r e a m R e a d e r ( System . in ));
System . out . print ( " Entrez votre prenom : " );
String prenom = flux . readLine ();
System . out . println ( " Bonjour " + prenom );
flux . close ();
} catch ( IOException ioe ) { System . err . println ( ioe ); }
}
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Flux d’entrée - Lecture à partir d’un fichier


Un fichier est représenté par un objet de la classe java.io.File.
Le constructeur de cette classe prend en paramètre d’entrée le chemin
d’accès du fichier.
Le flux d’entrée est alors créé à l’aide de la classe FileInputStream sur
lequel on peut lire caractère par caractère grâce à la méthode read().

L’exemple suivant présente une méthode pour afficher le contenu d’un fichier
import java . io .* ;
public class LectureFichier {
public static void main ( String [] args ) {
try {
File fichier = new File ( " monFichier . txt " );
F il eInputStream flux = new F il eI n pu tS tr e am ( fichier );
char c ;
while (( c = flux . read ()) > -1)
{
System . out . write ( c );
}
flux . close ();
} catch ( F i l e N o t F o u n d E x c e p t i o n e ) { e . p ri n tS ta c kT ra ce (); }
catch ( IOException e ) { e . p ri nt St a ck Tr ac e (); }
}
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Flux d’entrée - Lecture à partir d’un fichier


Il arrive souvent d’enregistrer des données dans des fichiers textes. Il peut
alors être utile d’utiliser un BufferedReader ou un Scanner pour effectuer
la lecture.
Exemple : on considère une matrice 10x10 enregistrée dans un fichier
matrice.txt ligne par ligne, avec les colonnes séparées par des espaces :
import java . io .* ;
public class LectureMatrice {
public static void main ( String [] args ) {
try {
FileReader fileReader = new FileReader ( " matrice . txt " );
BufferedReader reader = new Bu fferedRe ader ( fileReader );
while ( reader . ready ())
{
String [] line = reader . readLine (). split ( " " );
for ( String s : line )
System . out . print ( s + " " );
System . out . println ();
}
reader . close ();
fileReader . close ();
} catch ( F i l e N o t F o u n d E x c e p t i o n e ) { e . p ri n tS ta ck T ra ce (); }
catch ( IOException e ) { e . pr i nt St a ck Tr ac e (); }
}
}
Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 1
Gestion des exceptions - Gestion des entrées et des sorties

Flux d’entrée - Lecture à partir d’un fichier

On peut effectuer un traitement similaire avec la classe Scanner :

import java . io .* ;
import java . util . Scanner ;
public class L e c t u r e M a t r i c e S c a n n e r {
public static void main ( String [] args ) {
try {
File fichier = new File ( " matrice . txt " );
Scanner fileScanner = new Scanner ( fichier );
while ( fileScanner . hasNextLine ())
{
Scanner lineScanner = new Scanner ( fileScanner . nextLine ());
while ( lineScanner . hasNext ())
System . out . print ( lineScanner . next ());
System . out . println ();
}
} catch ( F i l e N o t F o u n d E x c e p t i o n e ) {
e . printStack Tr ac e ();
}
}
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 2
Gestion des exceptions - Gestion des entrées et des sorties

Flux d’entrée - Lecture d’objets enregistrés - Désérialisation


Il est parfois utile d’enregistrer l’état d’objet (de n’importe quelle classe
implémentant les interfaces java.io.Serializable ou
java.io.Externalizable) pour des exécutions futures.
Le flux d’entrée est encore créé à l’aide de la classe FileInputStream et est
ensuite encapsulé dans un autre flux spécifiant le format des données à lire.
Exemple : la lecture d’un objet de la classe Pixel dans un fichier nommé
monFichier.pxl :
import java . io .* ;
public class Pixel implements Serializable {......}
public class LecturePixel {
public static void main ( String [] args ) {
try {
File fichier = new File ( " monFichier . pxl " );
O b jec tIn putS tre am flux = new O b j e c t I n p u t S t r e a m (
new F il eI n pu tS tr e am ( fichier ));
Pixel pixel = ( Pixel ) flux . readObject (); /** L ’ objet qui est lu
dans le fichier doit ^ e tre une instance de la classe Pixel * */
System . out . println ( pixel . affiche ());
flux . close ();
} catch ( IOException ioe ) { System . err . println ( ioe ); }
catch ( C l a s s N o t F o u n d E x c e p t i o n cnfe ) { System . err . println ( cnfe ); }
}
}
Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 2
Gestion des exceptions - Gestion des entrées et des sorties

Flux de sortie

Un flux de sortie est une instance d’une sous-classe de OutputStream.


Comme pour les flux d’entrée, chaque classe de flux de sortie a son propre
mode d’écriture de données. Les classes les plus couramment utilisées sont :
I ByteArrayOutputStream permet d’écrire des octets vers le flux de sortie .
I DataOutputStream permet d’écrire des types de données primitifs de Java
vers le flux de sortie.
I FileOutputStream est utilisé pour écrire dans un fichier. Les objets de cette
classe sont souvent encapsulés dans un autre objet de classe OutputStream
qui définit le format des données à écrire.
I ObjectOutputStream permet d’écrire des objets (c-à-d des instances de
classes Java) vers le flux de sortie, si ces objets implémentent les interfaces
Serializable ou Externalizable.
I Writer n’est pas une sous-classe de OutputStream mais représente un flux de
sortie pour chaı̂nes de caractères.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 2
Gestion des exceptions - Gestion des entrées et des sorties

Flux de sortie - Ecriture dans un fichier

L’écriture dans un fichier se fait par un flux de la classe FileOutputStream


qui prend en entrée un fichier (instance de la classe File).
Ce flux de sortie permet d’écrire des caractères dans le fichier grâce à la
méthode write().

L’exemple suivant présente une méthode pour écrire un texte dans un fichier
import java . io .* ;
public class EcritureFich ie r {
public static void main ( String [] args ) {
try {
File fichier = new File ( " monFichier . txt " );
FileOutputStrea m flux = new F i l e O u t p u t S t r e a m ( fichier );
String texte = " Hello World ! " ;
for ( int i = 0 ; i < texte . length (); i ++)
{
flux . write ( texte . charAt ( i ));
}
flux . close ();
} catch ( F i l e N o t F o u n d E x c e p t i o n e ) { e . p ri n tS ta ck T ra ce (); }
catch ( IOException e ) { e . p ri nt St a ck Tr a ce (); }
}
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 2
Gestion des exceptions - Gestion des entrées et des sorties

Flux de sortie - Ecriture dans un fichier


On peut également utiliser un Writer comme un FileWriter pour écrire
des chaı̂nes de caractères dans un fichier assez simplement.
Exemple : on écrit une série de 10 lignes de 10 entiers aléatoires séparés par
des espaces dans un fichier pouvant être lu par la classe LectureMatrice :

import java . io .* ;
import java . util . Random ;
public class EcritureMatric e {
public static void main ( String [] args ) {
try {
FileWriter writer = new FileWriter ( " random . txt " );
Random generator = new Random ( System . c u r r e n t T i m e M i l l i s ());
for ( int i = 0 ; i < 9 ; i ++)
{
for ( int j = 0 ; j < 9 ; j ++)
writer . write ( generator . nextInt () + " " );
writer . write ( " \ n " );
}
writer . close ();
} catch ( F i l e N o t F o u n d E x c e p t i o n e ) { e . p ri n tS ta ck T ra ce (); }
catch ( IOException e ) { e . pr i nt St a ck Tr ac e (); }
}
}

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 2
Gestion des exceptions - Gestion des entrées et des sorties

Flux de sortie - Ecriture d’objets - Sérialisation

Le flux de sortie peut également être encapsulé dans un flux de type


ObjectOutputStream, comme le montre l’exemple suivant pour écrire le
pixel courante dans un fichier :

import java . io .* ;
public class Pixel implements Serializable {......}
public class EcriturePixel {
public static void main ( String [] args ) {
try {
File fichier = new File ( " monFichier . pxl " );
O b j e ct Ou t pu t St re a m flux = new O b j e c t O u t p u t S t r e a m (
new F i l e O u t p u t S t r e a m ( fichier ));
Pixel pixel = new Pixel (3 ,5);
flux . writeObject ( pixel );
flux . close ();
} catch ( IOException ioe ) {
System . err . println ( ioe );
}
}
}

Ce fichier peut ensuite être lu par la classe LecturePixel.

Pr. Abdessamad EL BOUSHAKI (ENSA de Fès) Programmation Orientée Objet avancée en JAVA 2