Programmation Orientée Objet (POO)
Java – 5
Exceptions
Licence Informatique
2009-2010
Jean-Louis Lanet/Benoit Crespin/Julien Cartigny
[Link]@[Link]
Agenda
• Exception,
• Exception,
• Exception,
• Exception,
• Exception,
• Exception,
• Exception,
• Exception
Principe
• Java dispose d’un mécanisme très souple nommé gestion
d’exception, qui permet :
– de dissocier la détection d’une anomalie de son traitement,
– de séparer la gestion des anomalies du reste du code, donc de
contribuer à la lisibilité des programmes.
• But : rendre le traitement des erreurs plus facile à
automatiser par modification du flot de contrôle,
• Mécanisme :
– Une rupture de séquence déclenchée par une instruction throw
comportant une expression de type classe,
– Branchement à un ensemble d’instructions nommé "gestionnaire
d’exception".
Principe des exceptions
• Un objet JAVA Exception est une « bulle » logicielle produite dans
cette situation qui va remonter la pile d’exécution pour trouver une
portion de code apte à la traiter,
• Si cette portion n’existe pas, le programme s’arrête en affichant la pile
d’exécution. Sinon, la portion de code sert à pallier au problème
(poursuite éventuelle, ou sortie)
• La plupart des exceptions doivent être “attrapées”, faute de quoi le
compilateur sévit.
• En Java, les exceptions sont des objets ayant 3 caractéristiques:
– Un type d’exception (défini par la classe de l’objet exception)
– Une chaîne de caractères (option), (hérité de la classe Throwable).
– Un « instantané » de la pile d’exécution au moment de la création.
Exemple d’erreur non gérée
public class testException1 {
public static void main ( String args []) {
int tab [] = new int [10];
tab [12] = 4;
[Link] ("tab 12] est modifie");
}
}
/*
Exception in thread "main" [Link]
Exception : 12 at [Link] ( testException1 . java
:4)
*/
Principe des exceptions
• Lorsqu’une méthode détecte une erreur, au lieu de retourner
une valeur caractéristique en espérant qu’elle soit traitée par
la méthode appelante, elle lance une exception (throw),
• Toute partie du code qui fait appel à cette méthode peut
attraper cette exception pour traiter le problème éventuel
(catch),
• Les exceptions construites par l'utilisateur étendent la classe
Exception
• Différencier les exceptions explicites (contrôlées) des
exceptions implicites (non contrôlées).
Hiérarchie
• Une exception est un objet de type Exception
– Instancier par n’importe quelle sous-classe d’Exception
• Hiérarchie RuntimeException et Error
– Une hiérarchie d’exceptions non contrôlées par le compilateur
– Error :
• NoSuchMethodError: la méthode référencée n’est pas accessible
• StackOverflowError: débordement de pile
– RunTimeException
• ArithmeticException: une erreur arithmétique (division par
0…)
• IndexOutofBoundsException: indice d’un tableau est en
dehors des bornes autorisées.
Quelques exceptions prédéfinies non
contrôlées en Java
• Division par zéro pour les entiers : ArithmeticException
• Référence nulle : NullPointerException
• Tentative de forçage de type illégale : ClassCastException
• Tentative de création d'un tableau de taille négative :
NegativeArraySizeException
• Dépassement de limite d'un tableau :
ArrayIndexOutOfBoundsException
Il n’est pas obligatoire de gérer les exceptions
de type RuntimeException
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 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
Object
Object
Throwable
Throwable
Exception
Exception Error
Error
InterruptedException IOException
IOException RunTimeException ParseException myExcep.
InterruptedException RunTimeException ParseException myExcep.
IndexOutOfBoundsException
IndexOutOfBoundsException ArithmeticException
ArithmeticException NullPointerException
NullPointerException
Levée d’une exception
• Une exception est un objet spécifique traité par la JVM. Si
une exception est lancée, la JVM :
– Arrête l’exécution du code dans la méthode où l’erreur se produit,
– Recherche la partie du code où se fait le traitement de l’erreur,
– Applique ce traitement puis reprend l’exécution après cette partie
du code.
• Structures spécialisées :
– try
– catch
– finally
Capture d'une exception
• Les sections try et catch servent à capturer une exception
dans une méthode (attraper la bulle…)
• Exemple :
Si une erreur se
public void XXX(………) { produit ici….
try{ …………… }
catch {
………
………
}
} On tente de récupérer là.
Verbotten !!!
• Le catch DOIT suivre le bloc try correspondant
public void XXX(………) {
try{ …………… }
[Link]("Test");
catch {
………
………
}
}
• Il est possible d’imbriquer les bloc try d’en avoir plusieurs
dans une méthode,…
Utiliser les exceptions
• On sépare le bloc d’instructions où une erreur peut se
produire du bloc de gestion des erreurs éventuelles :
try {
// Code pouvant lever des exceptions
}
catch ( IOException e) {
// Gestion des exceptions de type IOException
// ou de ses sous - classes
}
catch ( Exception e) {
// Gestion de toutes les autres exceptions autant de catch
} // que l’on a besoin
...
finally {
// Lorsque toutes les exceptions ont été gérées ,
// on exécute ce bloc } // facultatif
Exemple d’erreurs gérées par des
exceptions
public class testException2 {
static int tab [] = new int [10];
public static void operations () {
tab [12] = 4;
[Link] ("tab [12] est modifie");
Object x = new Integer (0) ;
String y = ( String )x;
[Link] (" Affichage : " + y);
}
public static void main ( String args []) {
try {
operations ();
}
catch ( ArrayIndexOutOfBoundsException e) {
[Link] ("indice non valide !");
}
catch ( ClassCastException e) {
[Link] ("conversion non valide !");
}
finally {
[Link] (" Une erreur est survenue ");
}
[Link] ("Je continue mon exécution ... ");
}
}
Toutes les exceptions héritent de Exception
public class testException3 {
static int tab [] = new int [10];
public static void operations () {
tab [12] = 4;
[Link] (" tab [12] est modifie ");
…
}
public static void main ( String args []) {
try {
operations ();
}
catch (Exception e) {
[Link] (" Une exception a ete levee ");
[Link] ();
}
[Link] ("Je continue mon execution ... ");
}}
Plus en détail...
• Le bloc try est exécuté jusqu'à ce qu'il se termine avec succès
ou bien qu'une exception soit levée.
• Dans ce dernier cas, les clauses catch sont examinées l'une
après l'autre dans le but d'en trouver une qui traite cette classe
d'exceptions (ou une superclasse) acceptant de gérer l’erreur.
• Deux cas possibles :
– Le bloc existe, il est exécuté, et l’éventuel bloc finally est ensuite
exécuté
– S’il n’existe pas, alors l’exception est transmise à la méthode appelante
après exécution du finally. Dans ce cas, la signature de la méthode
doit indiquer qu’elle est susceptible de propager une exception :
void uneMethode(...) throws IOException ...
Transmission
• Que ce passe t il dans cet exemple ?
class ErrConst extends Exception { }
class ErrDepl extends Exception { }
public void deplace (int dx, int dy) throws ErrDepl{}
public void f (...) {
try {
Point a = new Point(2, 5) ;
[Link] (2, 5) ;
} catch (ErrConst) { ..... }
}
Sortie
• Que ce passe t il dans cet exemple si une ErrDepl est jetée?
class ErrDepl extends Exception { }
public void deplace (int dx, int dy) throws ErrDepl{}
public int f (...) {
try {
Point a = new Point(2, 5) ;
[Link] (2, 5) ;
} catch (ErrDepl) { return 1 }
[Link] ("Je continue mon execution ... ");
return 2;
}
Plus en détail...
• Les clauses catch doivent donc traiter les exceptions de la
plus spécifique à la plus générale.
• Si une exception n'est jamais capturée, elle se propage jusqu'à la
méthode main(), ce qui pousse l'interpréteur Java à afficher un
message d'erreur et à s'arrêter.
• Une exception peut aussi être propagée manuellement après
traitement, ou bien lancée manuellement à l’aide de : throw
uneException ;
• Vous pouvez définir vos propres exceptions, qui doivent hériter
de la classe Exception.
Bloc finally
• Un bloc finally permet au programmeur de définir un
ensemble d'instructions qui est toujours exécuté, que
l'exception soit levée ou non, capturée ou non.
• La seule instruction qui peut faire qu'un bloc finally ne
soit pas exécuté est [Link]().
class CompteurException extends Exception {…}
public class Compteur {
private int val_max ;
private int val_compteur ;
public Compteur ( int max ) {
val_max = max;
val_compteur = 0;
}
private int suiv () throws CompteurException {
if ( val_compteur == val_max )
throw new CompteurException ();
else return val_compteur ++;
}
public void compte () {
try {
while ( true ) {
[Link] ("Compteur= "+ suiv ());
}
}
catch ( CompteurException e) {
[Link] ("Fin du compteur atteinte");
}
}
public static void main ( String args []) {
Compteur c = new Compteur (10) ;
c. compte ();
}
}
Autre exemple
class Compteur2Exception extends Exception {}
public class Compteur2 {
private int val_max ;
private int val_compteur ;
public Compteur2 ( int max) {
val_max = max;
val_compteur = 0;
}
private int suiv () throws Compteur2Exception {
if ( val_compteur == val_max )
throw new Compteur2Exception ();
else return val_compteur ++;
}
public void compte () throws Compteur2Exception {
while ( true ) {
[Link] ("Compteur ="+suiv ());}
}
public static void main ( String args []) {
Compteur2 c = new Compteur2 (10) ;
try {
[Link] ();
}
catch ( Compteur2Exception e) {
[Link] ("Fin du compteur atteinte");
}
}
}
Attention à l’ordre des catch
class ErrPoint extends Exception { ..... }
class ErrConst extends ErrPoint { ..... }
class ErrDepl extends ErrPoint { ..... }
...
void f () {
.....
throw ErrConst ;
.....
throw ErrDepl ;
}
...
try
{ … f(); …
}
catch (ErrPoint e)
{ }
Bloc finally
• Un bloc finally permet au programmeur de définir un
ensemble d'instructions qui est toujours exécuté, que
l'exception soit levée ou non, capturée ou non.
• La seule instruction qui peut faire qu'un bloc finally ne
soit pas exécuté est [Link]().
Récapitulatif
class Except extends Exception {
public Except (int n) { this.n = n ; } Que produit le programme suivant lorsqu’on
public int n ; } lui fournit en donnée :
public class Chemin {
• la valeur 0,
• la valeur 1,
public static void main (String args[]) { • la valeur 2.
int n ;
[Link] ("donnez un entier : ") ; n = [Link]() ;
try {
[Link] ("debut premier bloc try") ;
if (n!=0) throw new Except (n) ;
[Link] ("fin premier bloc try") ;
}
catch (Except e) { [Link] ("catch 1 - n = " + e.n) ; }
[Link] ("suite du programme") ;
try
{ [Link] ("debut second bloc try") ;
if (n!=1) throw new Except (n) ; [Link] ("fin second bloc try") ;
}
catch (Except e) {
[Link] ("catch 2 - n = " + e.n) ; [Link](-1) ; }
[Link] ("fin programme") ;
}
}
Le compilateur couine-t-il ?
public point (int a)
try {
...
if (...) throw myException;
...
}
finally
{ // instructions A
}
... // suite
Any question ?