Programmation Orientée Objet Introduction à Java

Transcription

Programmation Orientée Objet Introduction à Java
Programmation Orientée Objet
Exceptions et assertions
Julien Provillard
http://www.i3s.unice.fr/~provilla/poo/
[email protected]
Programmation orientée objet
Objectifs
Robustesse et Exceptions
 Error, RuntimeException
 Exceptions (non) contrôlées
 try catch, finally, ressources
Correction et Assertions
 Mot clé assert
2
Programmation orientée objet
Fiabilité d’un programme
Correction
 Donne un résultat correct lorsqu’il fonctionne en mode "normal"
 Les assertions permettent de vérifier qu’on est dans un mode "normal"
Robustesse
 Fonctionne même lorsque l’environnement ne respecte pas le contrat (données
erronées, état inconsistant)
 Les exceptions permettent de gérer des anomalies lors de l’exécution et de
rétablir un environnement stable ou de sortir proprement du programme.
3
EXCEPTIONS
Représentent des évènements anormaux du système
4
Programmation orientée objet
Les exceptions sont des objets
La classe Exception représente des évènements anormaux (qui ne
doivent pas se produire lors d’une exécution normale).
 Il faut décrire le fonctionnement normal du programme dans un bloc try
 Prévoir (éventuellement) des situations anormales dans un/des bloc(s) catch
 Réagir à ces situations anormales pour pallier aux erreurs éventuelles
(normalement exceptionnelles/rares) de l’environnement
On peut lever/lancer les exceptions (instances)
 throw uneException;
 Permet de séparer la détection d’une anomalie de son traitement
 Provoque une rupture du flot d’exécution
5
Programmation orientée objet
NumberFormatException: try/catch
On peut attraper les exceptions pour détecter une erreur
class Somme {
static public void main(String[] args) {
int somme = 0;
catch:
for(String arg : args) { try:
Fonctionnement normal Fonctionnement exceptionnel en cas d’erreur
try {
somme += Integer.parseInt(arg);
} catch (NumberFormatException e) {
System.err.println(arg + " n’est pas un nombre!");
}
}
Test :
System.out.println("Somme = " + somme);
java Somme 12 pasUnNombre 14
}
pasUnNombre n’est pas un nombre!
}
Somme = 26
6
Programmation orientée objet
Synopsis: try catch
try {
// fonctionnement normal
…
} catch (XXXException e) {
// cas si XXXException se produit
} catch (YYYException e) {
// cas si YYYException se produit
}
 Attention:




On ne peut pas attraper une exception qui ne peut pas être lancée! (erreur de
compilation)
XXXException peut être une sous-classe de YYYException
YYYException ne peut pas être une sous-classe de XXXException
Les exceptions levées en dehors de try (avant, dans le catch, après) ne sont pas
attrapées
7
Programmation orientée objet
Traitement des exceptions
Une méthode peut décider
 D’attraper les exceptions lancées et les traiter
 De propager les exceptions
• Il faut le déclarer dans la signature de la méthode selon la nature
• Ex: FileReader(String pathname) throws FileNotFoundException
 D’attraper et les relancer ou d’en lancer d’autres (à déclarer)
Propagation
 C’est la méthode appelante qui la récupère
 La méthode main peut aussi propager des exceptions
8
Programmation orientée objet
Traitement des exceptions
Dans un bloc try
 Le code entre l’instruction qui a levée l’exception et la fin du bloc try n’est pas
exécuté
 Le premier bloc catch compatible est exécuté
 L’exécution se poursuit normalement après le dernier bloc catch !
9
Programmation orientée objet
Traitement des exceptions
Pas d’exception levée : Si aucune exception n’est levée dans le bloc try
 Alors les blocs catch sont ignorés
 L’exécution se poursuit normalement après le dernier bloc catch
10
Programmation orientée objet
Traitement des exceptions
Exception pas attrapée
 Certaines exceptions ne sont pas obligatoirement attrapées (RuntimeException)
 Le message porté par l’exception est affiché
 Le Thread dans lequel l’exception a été lancée meurt
• Les autres continuent leur exécution
Dans la méthode main
 La méthode main peut aussi propager les exceptions !
11
Programmation orientée objet
java.lang.Throwable
Toutes les exceptions sont de type Throwable
Throwable
Error
Exception
RuntimeException
XXXException
YYYException
12
Programmation orientée objet
java.lang.Throwable
Toutes les exceptions sont de type Throwable
Throwable
Erreurs graves
JVM
Error
Exception
RuntimeException
XXXException
YYYException
13
Programmation orientée objet
Error
Réservées aux erreurs de la JVM
 OutOfMemoryError
 NoSuchMethodError
Recommandations




Ne devraient pas arriver
Très rare qu’on les attrape
Ne devraient pas être lancées par les utilisateurs
Pas de raison de faire des classes filles
14
Programmation orientée objet
java.lang.Throwable
Toutes les exceptions sont de type Throwable
Throwable
Error
Exceptions noncontrôlées par le
compilateur
try/catch optionnel
Exception
RuntimeException
XXXException
YYYException
15
Programmation orientée objet
RuntimeException
Usage
 A priori si l’on pense que le problème ne pourra pas être résolu (dans un catch)
 Pour ne pas forcer à alourdir le code
Quelques RuntimeException




NullPointerException
ArrayIndexOutOfBoundsException
NumberFormatException
ClassCastException
16
Programmation orientée objet
java.lang.Throwable
Toutes les exceptions sont de type Throwable
Throwable
Exceptions contrôlées
=> try/catch obligatoire
Error
Exception
RuntimeException
XXXException
YYYException
17
Programmation orientée objet
Exceptions contrôlées
 Définition
 Doivent être
• Soit attrapées (try/catch)
• Soit propagées (throws dans la signature)
 Contaminant vers la méthode appelante
 Attention
 Peut avoir un throws sans lancer l’exception
 Peut propager plusieurs exceptions dans un throws
 Ne peut pas avoir un catch si l’exception ne peut pas être lancée
 Quelques exceptions contrôlées
 ClassNotFoundException
 IOException (toutes celles de java.io)
• EOFException
• FileNotFoundException
 InterruptedException
18
Programmation orientée objet
Lancer une exception
L’utilisateur peut lancer des exceptions
 Soit en utilisant les classes prédéfinies
 Soit en définissant de nouvelles classes qui héritent de RuntimeException ou
de Exception
 Peut avoir à instancier un nouvel objet
Exemple:
class Validate {
public static void notNull(Object obj) {
if (obj == null)
throw new NullPointerException("The object must not be null");
}
}
19
Programmation orientée objet
Exemple: CompteBancaire
Le crédit d’un montant négatif n’est pas prévu
class CompteBancaire {
int solde = 0;
void crediter(int somme) {
if (somme < 0)
throw new IllegalArgumentException("somme négative illégale!");
solde += somme;
}
}
Note:

IllegalArgumentException est une RuntimeException
20
Programmation orientée objet
Définir ses propres exceptions
 Exception non-contrôlée
class DecouvertException extends RuntimeException {
CompteBancaire compte;
DecouvertException(CompteBancaire c) {
super("Découvert non autorisé sur " + c);
this.compte = c;
}
}
 Usage
class CompteBancaire {
int solde = 0;
void debiter(int somme) {
if (somme > solde) throw new DécouvertException(this);
solde -= somme;
}
}
21
Programmation orientée objet
Exceptions et redéfinition
Quand on redéfinit une méthode, on ne peut pas déclarer plus
d’exceptions contrôlées que la méthode redéfinie
Il faut renvoyer :
 les mêmes exceptions
 Ou des sous-classes de ces exceptions
 Ou moins d’exceptions (éventuellement aucune)
22
Programmation orientée objet
Exceptions dans les constructeurs
Si une exception est levée dans un constructeur
 Et qu’elle n’est pas attrapée par le constructeur
 Alors aucune instance n’est créée
23
Programmation orientée objet
Définir ses propres exceptions
 Exception contrôlée
class DecouvertException extends Exception {
CompteBancaire compte;
DecouvertException(CompteBancaire c) {
super("Découvert non autorisé sur " + c);
this.compte = c;
}
}
 Usage
class CompteBancaire {
int solde = 0;
void debiter(int somme) throws DecouvertException {
if (somme > solde) throw new DecouvertException(this);
solde -= somme;
}
}
24
Programmation orientée objet
Exceptions vs tests
Exemple : Tentative d’ouverture d’un fichier
public static FileReader openFile(String path) {
try {
return new FileReader(path);
} catch (FileNotFoundException ex) {
return null; // cas réellement exceptionnel?
}
}
On gère une exception que l’on aurait pu prévoir. Le chemin existe-t-il?
Désigne-t-il un fichier? Celui-ci est-il accessible?
Attraper une exception a un coût élevé, il ne faut pas se baser sur les
exceptions pour gérer des cas prévisibles.
25
Programmation orientée objet
Exceptions vs tests
Exemple : Tentative d’ouverture d’un fichier
public static FileReader openFile(String path) {
File file = new File(path);
FileReader reader = null;
if (file.exists() && file.isFile() && file.canRead()) {
try {
reader = new FileReader(file);
} catch (FileNotFoundException ex) {
} // Vraiment un cas exceptionnel!
}
return reader;
}
26
LES ASSERTIONS
Pré et post-conditions
27
Programmation orientée objet
Mot clé assert
Depuis le JDK 1.4
 assert boolean_expression;
 assert boolean_expression : "message d’erreur";
Permet de s’assurer qu’une propriété est vraie
 Si l’expression booléenne est vraie, rien ne se passe
 Sinon, une AssertionError est lancée
Usage
 Pré-condition: au début d’une méthode
 Post-condition: à la fin d’une méthode
 Invariant: au milieu d’un code compliqué (boucle)
28
Programmation orientée objet
Exemple: CompteBancaire
Le crédit d’un montant négatif n’est pas prévu
class CompteBancaire {
int solde = 0;
void crediter(int somme) {
assert somme >= 0 : "somme négative illégale :" + somme;
solde += somme;
}
}
Note:
 En général, ce sera garanti par l’environnement d’appel (interface graphique,
application principale, …)
29
Programmation orientée objet
Activation
Activation
 Lors de l’exécution
• Si on n’active pas (comportement pas défaut), alors le code est ignoré
• Si on active, cela peut produire des exceptions
Test vs. Production
 Pendant les tests, les assertions sont activées
 En production, les assertions sont normalement désactivées
30
Programmation orientée objet
Activation
Pour activer les assertions
 java –ea
Pour activer pour un paquetage ou une classe
 java –ea:<nom-paquetage>...
 java –ea:<nom-classe>
Pour désactiver pour un paquetage ou une classe
 java –ea –da:<nom-paquetage>...
 java –ea –da:<nom-classe>
31
Programmation orientée objet
Assertions ou exceptions?
Les exceptions doivent être utilisées
 Pour vérifier la correction des paramètres des méthodes publiques
 Lorsqu’une situation exceptionnelle se produit
 Pour gérer ces situations exceptionnelles
Les assertions doivent être utilisées
 Pour les pré et post-conditions et les invariants de boucles des méthodes privées
(sauf si une exception doit être remontée à la méthode appelante)
 Pour vérifier qu’une propriété attendue est vraie
De manière générale, les exceptions assurent la robustesse du code
tandis que les assertions vérifient sa correction (une AssertionError
devrait indiquer une erreur de programmation)
32
Programmation orientée objet
Assertions ou exceptions?
 Exception contrôlée
class DecouvertException extends Exception {
CompteBancaire compte;
DecouvertException(CompteBancaire c) {
super("Découvert non autorisé sur " + c);
this.compte = c;
}
Assertion : l’environnement
}
 Usage
d’appel est sensé
vérifier que toutes les sommes manipulées
sont positives
class CompteBancaire {
int solde = 0;
void debiter(int somme) throws DecouvertException {
assert somme >= 0 : "somme négative illégale :" + somme;
if (somme > solde) throw new DécouvertException(this);
solde -= somme;
}
Exception : l’appel de méthode
}
est valide
mais entraîne une situation exceptionnelle
33
COMPLÉMENTS SUR LES EXCEPTIONS
34
Programmation orientée objet
Multi-catch (JDK 7.0)
try {
// fonctionnement normal
} catch (XXXException e) {
// cas si XXXException se produit
} catch (YYYException e) {
// cas si YYYException se produit
}
Que faire si les deux blocs sont
identiques pour éviter la
duplication du code?
Solution n°1 :
Attraper un ancêtre commun de
XXXException et YYYException
try {
// fonctionnement normal
} catch (Exception e) {
/* cas si XXXException ou
* YYYException se produit
*/
}
Mauvaise pratique, on attrape
désormais toutes les exceptions!
35
Programmation orientée objet
Multi-catch (JDK 7.0)
try {
// fonctionnement normal
} catch (XXXException e) {
// cas si XXXException se produit
} catch (YYYException e) {
// cas si YYYException se produit
}
Que faire si les deux blocs sont
identiques pour éviter la
duplication du code?
Solution n°2 :
Factoriser dans une méthode
try {
// fonctionnement normal
} catch (XXXException e) {
someMethod(...);
} catch (YYYException e) {
someMethod(...);
}
Fastidieux, il peut être nécessaire
de passer beaucoup d’informations
à la méthode.
36
Programmation orientée objet
Multi-catch (JDK 7.0)
try {
// fonctionnement normal
} catch (XXXException | YYYException e) {
// cas si XXXException ou YYYException se produit
}
 Attention:

e est final

XXXException : pas un sous-type de YYYException

YYYException : pas un sous-type de XXXException
37
Programmation orientée objet
Propager les exceptions
Il ne faut pas attraper les exceptions trop vite
 Choisir le niveau le mieux adapté pour retrouver un état « normal »
 On attrape que si l’on est sûr de ne pas avoir un état dégradé après
 Il est possible d’attraper une exception pour rétablir partiellement l’état du
système avant de la relancer au niveau supérieure.
 Au plus près de la cause de l’exception
Les blocs try et catch sont des blocs d’instructions
 Les variables déclarées dans ces blocs meurent à la fin du bloc
 try et catch sont deux blocs séparés !
• Le bloc catch ne connaît pas les variables déclarées dans le bloc try
38
Programmation orientée objet
Throwable.printStackTrace()
La méthode printStackTrace
 Affiche l’état de la pile au moment de l’exception
 C’est-à-dire la liste des méthodes qui ont conduit à l’exception (avec le numéro
de ligne)
 Voir aussi Throwable.printStackTrace(PrintWriter)
java.io.FileNotFoundException: ..\reference.txt.cs (Le fichier spécifié est introuvable)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
at java.util.Scanner.<init>(Unknown Source)
at fr.unice.cesar.BarChart.init(BarChart.java:36)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
printStackTrace peut exposer des informations sensibles!
39
Programmation orientée objet
Synopsis: try[-catch]-finally
try {
// fonctionnement normal
} catch (XXXException e) {
// cas si XXXException se produit
} finally {
// le mot de la fin (dans tous les cas)
}
 Bloc finally:

Exécuté dans tous les cas

• qu’il y ait eu ou non une exception
• Même s’il y avait un return dans le try et/ou catch
finally est exécuté
• Après le try, après le catch
• Avant de passer la main à la méthode appelante
40
Programmation orientée objet
finally vs. try/catch
 finally est prioritaire sur ce qui se passe dans try et catch
 Si une exception est levée dans finally alors le return du try et du catch ne se
produisent pas
 Si finally contient un return alors les exceptions propagées dans le try ou catch
ne sont pas lancées
 Si finally ne fait ni return ni throw alors l’exception ou la valeur renvoyée dans
le try/catch sont prises en compte !
Convention:
 Il faut éviter cette situation
41

Documents pareils