Vous êtes sur la page 1sur 9

Exceptions - Sérialisation

Erreurs d'exécutions
 Dans tout programme, il y a des erreurs d'exécution possibles , des
cas particuliers qui n'ont pas forcément été traités. On ne vise pas à les
supprimer, mais à les controler (robustesse du code, tolérance aux
erreurs)
 il s'agit d'erreurs d'exécution, pas d'erreur de programmation que le compilateur peut
détecter.
 Exemple : un fichier que le programme essaie de lire est déjà utilisé par une autre
application

 Quand il y a une erreur, on voudrait se retrouver dans un endroit du


programme d’où l’on peut récupérer de l’erreur :
 Exemple : une méthode utilise un nombre passé en paramètre, nombre par lequel on
divise un autre nombre. Ce nombre est donné par l'utilisateur. Si ce nombre vaut 0,
on veut que l'erreur qu'il déclenche soit traitée au niveau de l'interaction avec
l'utilisateur, et non à l'intérieur de la méthode.

 L'erreur doit donc pouvoir être propagée et véhiculer une description


pour être traitée en dehors du contexte où elle s'est produite

=> Exception
Licence Informatique - Semestre 6 - Compléments de Java 1

La gestion d’une exception


 Le principe d’endiguement :
 Un programme est une hiérarchie de contextes d’exécution
 Une erreur n’est visible qu’à l’intérieur d’un contexte dans cette hiérarchie
 Une routine de récupération existe à l’interface d’un contexte d’exécution,
pour que l’erreur ne se propage pas vers un niveau plus elevé

Une erreur qui lève


saut une exception

Un contexte
d’exécution

Le contexte
d’exécution qui
attrape l’exception

Un programme qui rencontre une erreur doit en transférer le traitement à une


autre partie (“exception handler”) et lui donner une valeur qui décrit l’erreur
(l’“exception” proprement dite)
Licence Informatique - Semestre 6 - Compléments de Java 2

1
Exceptions - Sérialisation

Exceptions en Java
 Checked exceptions : exceptions déclarées, traitées ou propagées par
le code (comportement exceptionnel mais prévu). Le compilateur vérifie
que les méthodes ne lèvent que les exceptions déclarées pour la classe.

 Unchecked exceptions : exceptions non traitées et non propagées dans


le code. Le compilateur ne les vérifie pas (comportement non prévu).
Elles héritent de RuntimeException et Error.
Object

Throwable

Exception Error
...

ClassNotFoundException AWTException VirtualMachineError

RuntimeException
... StackOverFlowErrorOutOfMemoryError

NullPointerException ArithmeticException...
Licence Informatique - Semestre 6 - Compléments de Java 3

Lancement des exceptions


 Les exceptions sont lancées par le mot clé throw. Une méthode
dans le corps de laquelle une exception est lancée doit le signaler
par un bloc throws.
public static void parseFile(String fileName) throws FileNotFoundException,
ParseException,IOException{
File f = new File(fileName);
BufferedReader stream = new BufferedReader(new InputStreamReader(new
FileInputStream(f)));
// FileInputStream peut lancer une FileNotFoundException
// readLine peut lancer une IOException
if(!stream.readLine().equals("file header")) throw new
ParseException("Entête de fichier incorrecte ligne 1",0);
else{
...
}
}

 Si l'exception remonte jusqu'à la JVM, le thread qui a lancé


l'exception est interrompu
public void static main(String[] args) throws FileNotFoundException{
MyClass.parseFile("MyFile");
}

Licence Informatique - Semestre 6 - Compléments de Java 4

2
Exceptions - Sérialisation

Traitement des exceptions


try{
// contexte d'exécution. Peut contenir une instruction (méthode) qui lance une exception.
MyClass.parseFile("MyFile");
...
}
catch(FileNotFoundException e){

}
System.out.println(e.getMessage());
ExceptionTest1
catch(ParseException e){
e.printStackTrace(System.out);
}
catch(IOException e){
System.out.println("Problème d'accés fichier");
} ExceptionTest2
finally{
// optionnel. Bloc exécuté quelque soit les cas (exception levée ou pas). Il sert à faire le
// ménage, fermer des fichiers ouverts dans le bloc try par exemple
}

 Un seul bloc catch est exécuté, le premier rencontré qui correspond au type de
l'exception. Attention : si on essaie de récupérer une exception déjà récupérée
dans un bloc catch précédent (surclassée par exemple), le compilateur gueule
(il ne sait plus quel traitement appliquer)
Licence Informatique - Semestre 6 - Compléments de Java 5

Exceptions et constructeurs
 Si une exception est levée dans un constructeur, l'objet n'est pas
créé. Cela permet de contrôler les paramètres du constructeur
public class GroupeEtudiants{

private int nbEtudiants;

public GroupeEtudiants(int nb) throws IllegalArgumentException{


if(nb < 1) throw new IllegalArgumentException("Trop peu d'étudiants!");
else this.nbEtudiants = nb;
}

public static void main(String[] arg){


GroupeEtudiants ge;
try{
ge = new GroupeEtudiants(0);
GroupeEtudiants
System.out.println("Premier groupe " + ge);
}
catch(IllegalArgumentException e){System.out.println("Echec");}
try{
ge = new GroupeEtudiants(4);
System.out.println("Deuxième groupe " + ge);
}
catch(IllegalArgumentException e){System.out.println("Echec");}
}

Licence} Informatique - Semestre 6 - Compléments de Java 6

3
Exceptions - Sérialisation

Créer ses propres exceptions


 Il suffit de sous classer la classe Exception
/** Exception lancée en cas de clic sur un bouton */
public class ButtonException extends Exception{

public ButtonException(){
super("Button clicked");
}

 C’est très mauvais d’utiliser les exceptions pour modifier l’ordre d’exécution
dans une situation normale (ralentissement, non sérialisation des
comportements, ...)

 Attention au bon usage des exceptions :


 les exceptions doivent être exceptionnelles
 ce ne sont pas des structures de contrôle!
 éviter de capter les erreurs graves du style NullPointerException, il vaut mieux
les propager
 On peut toujours utiliser Exception, mais il vaut mieux utiliser la classe la plus
précise, pour avoir le maximum d'info sur l'erreur, et en plus les traitements au dessus
dépendent du type donc pour mieux canaliser et traiter l'erreur, faut préciser
Licence Informatique - Semestre 6 - Compléments de Java 7

Instruction avec clause “finally”


try {
for (;;) process (stream.next());
}
catch(StreamEndException e){stream.close();}

 Trouver la fin d’un flux est tout à fait normal, ce n’est pas une erreur!
try {
for (;;) process (stream.next());
}
catch(ExceptionType1 e){...}
...
finally{stream.close();}

 La sortie d'un bloc try se produit quand :


 le bloc se termine normalement
 une exception est levée et interrompt l'exécution du bloc
 le bloc exécute une instruction return, break ou continue
 Dans tous les cas, le bloc finally, s'il existe, est
obligatoirement exécuté après
Licence Informatique - Semestre 6 - Compléments de Java 8

4
Exceptions - Sérialisation

Sérialisation (1/3)

 En programmation objet, l'idée de réutilisabilité est essentielle. On peut


réutiliser le code facilement car il est structuré en briques élémentaires,
les classes
 On veut pouvoir aussi réutiliser les données créées par un programme,
il faut donc non plus sauver les classes (descriptions communes d'un
ensemble d'objets) mais les objets eux-mêmes qui encapsulent des
valeurs d'attributs
 Principe de la sérialisation : il s'agit de permettre la persistance des
objets, c'est-à-dire que la durée de vie de l'objet est supérieure à celle
du programme qui l'a créé. L'objet est sauvegardé dans un flux et
pourra être reconstitué plus tard dans l'état où il a été sauvegardé. On
sauve donc les valeurs de ses attributs et la manière de recréer l'objet
 Applications :
 stockage de données structurées
 échanges d'objets entre applications distribuées
 RMI (Remote Method Interface) : permet d'utiliser des objets distants (ne s'exécutant
pas sur la même JVM). Les objets sont transmis par sérialisation.
 Beans
Licence Informatique - Semestre 6 - Compléments de Java 9

Sérialisation (2/3)

 Tout objet implémentant l'interface Serializable est sérialisable


dans un flux (fichier, réseau, ...)
 Serializable n'a aucune méthode, elle ne sert qu'à identifier les objets
sérialisables

 La sérialisation est effectuée par writeObject(Object o),


méthode de l'interface ObjectOutput
 généralement, on utilise un ObjectOutputStream, classe qui implémente
ObjectOutput

 Dans l'implémentation ObjectOutputStream, o doit implémenter


Serializable sinon une NotSerializableException est levée

 peut lancer une IOException en cas de problème d'accès au flux


 la sérialisation d'un objet o sérialise également tous les objets référencés par o
(ces objets doivent donc être sérialisables sinon exception!)

Licence Informatique - Semestre 6 - Compléments de Java 10

5
Exceptions - Sérialisation

Sérialisation (3/3)

 comportement par défaut de la sérialisation : toutes les valeurs des champs


non static ou transient sont sauvées dans l'objet ObjectOutput. Des
informations sur la classe (types et noms des attributs) sont aussi sauvées
pour permettre de recréer l'objet.

 La désérialisation est effectuée par Object readObject(),


méthode de ObjectInput
 peut lancer une ClassNotFoundException car recherche la classe de
l'objet à recréer (appel au constructeur)

 peut lancer une IOException en cas de problème d'accès au flux


 Il faut bien sur caster l'objet retourné
 les champs transient sont positionnés à null

Licence Informatique - Semestre 6 - Compléments de Java 11

Sérialisation dans un fichier


public class MyPoint implements Serializable{

private int x,y;


private transient String name;

public MyPoint(int x, int y, String name){

MyPoint
this.x = x;this.y= y;
this.name = name;
}

public String toString(){return name + "(" + x + "," + y + ")";}

public static void main(String[] arg){


try{
MyPoint p = new MyPoint(1,2,"A");
File f = new File("MyPoint.sav");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
oos.writeObject(p);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
MyPoint pPrime = (MyPoint) ois.readObject();
System.out.println("p = " + p.toString());
System.out.println("pPrime = " + pPrime.toString());
System.out.println(p.equals(pPrime));
}
catch(Exception e){}
}

Licence
} Informatique - Semestre 6 - Compléments de Java 12

6
Exceptions - Sérialisation

Clonage
 Principe du clonage : construire un objet identique à un objet
donné vis-à-vis de son état (valeurs des attributs).
 l'objet clone est un nouvel objet, il n'a pas la même adresse mémoire
 Motivations pour un clonage :
 préserver un objet sensible en ne transmettant qu'une copie de cet objet
 préserver l'état d'un objet avant un traitement pour pouvoir revenir à l'état
initial
 créer un objet à moindre coût (par exemple si l'appel au constructeur d'un
objet exécute une requête sur une base de données)

 Deux types de clonages :


 clonage de surface : on affecte aux attributs du clone les valeurs des
attributs de l'objet cloné
 clonage en profondeur : on affecte aux attributs du clone des clones en
profondeur des attributs de l'objet cloné

Licence Informatique - Semestre 6 - Compléments de Java 13

Types de clonage (1/2)


Objet A Objet B
attribut1 attribut3 ...

attribut2
Objet C
clonage de
Objet A' attribut4 ...

surface attribut1
attribut2

clonage en Objet A'' Objet B'


profondeur attribut1 attribut3 ...

attribut2
Objet C'
attribut4 ...

Licence Informatique - Semestre 6 - Compléments de Java 14

7
Exceptions - Sérialisation

Types de clonage (2/2)


 Clonage profond : on s'arrête dans le clonage récursif quand les
attributs sont des variables primitives (int, boolean, ...) ou des
objets immuables (de contenu constant, ne contenant pas
d'attribut vers d'autres objets) comme String
 Clonage semi-profond : on ne clone que jusqu'à une certaine
profondeur
 Exemple de clonage de surface : duplication d'une liste d'éléments, sans
clonage des éléments eux-mêmes. Vector, LinkedList, ArrayList, etc,
implémentent une méthode Object clone() qui renvoie une copie d'eux-
mêmes, avec un clonage de surface

public static void main(String[] arg){


Vector v = new Vector();
v.add("un");v.add("deux");v.add("trois");
Vector vClone = (Vector) v.clone();
ShallowCopy
System.out.println("Contenus de v " + v + " et de son clone " + vClone);
v.add("quatre");
System.out.println("Contenus de v " + v + " et de son clone " + vClone);
}

Licence Informatique - Semestre 6 - Compléments de Java 15

Méthode clone
 En fait, Object clone() est une méthode (protégée) d'Object
 par défaut, elle crée un objet de même classe que l'objet sur lequel elle est
appelée et affecte au nouvel objet les attributs (non static) de l'objet original
(clonage de surface)
 elle déclenche une CloneNotSupportedException si la classe de l'objet
n'implémente pas l'interface Cloneable

 L'interface Cloneable est une interface de marquage, sans


méthode. Object ne l'implémente pas, donc appeler la méthode
clone() par défaut sur un objet lève une exception. Pour utiliser
clone(), il faut implémenter Cloneable (sauf si la classe en
hérite).

 Clonage et héritage :
 redéfinition de clone() pour cloner les nouveaux attributs (si nécessaire)
 appel de super.clone() pour créer les attributs de la super-classe
 ne pas utiliser les constructeurs dans clone!! (on veut souvent l'éviter
justement)

Licence Informatique - Semestre 6 - Compléments de Java 16

8
Exceptions - Sérialisation

Clonage et héritage (1/2)


public class DeepCopy extends Vector{

private String name;

public DeepCopy(String name){


super();
this.name = name;
}

public Object clone(){return new DeepCopy(this.name);}

public String toString(){return this.name + super.toString();}

public Object totalClone(){


Vector result = (Vector) super.clone();
DeepCopy dc = new DeepCopy(this.name);
for(Iterator i = result.iterator();i.hasNext();){
dc.add(i.next());
}
return result;
}

Licence Informatique - Semestre 6 - Compléments de Java 17

Clonage et héritage (2/2)


public static void main(String[] arg){
DeepCopy dc = new DeepCopy("first");
dc.add("un");dc.add("deux");dc.add("trois");
DeepCopy dcClone = (DeepCopy) dc.clone();
DeepCopy dctClone = (DeepCopy) dc.totalClone();
DeepCopy
System.out.println("Contenus de dc " + dc + " et de son clone de surface " +
dcClone);
System.out.println("Contenus de dc " + dc + " et de son clone profond " +
dctClone);
}

 Clonage et sérialisation : une sérialisation suivie d'une


désérialisation est un clonage profond!!

Licence Informatique - Semestre 6 - Compléments de Java 18

Vous aimerez peut-être aussi