• Aucun résultat trouvé

Erreurs d'exécutions

N/A
N/A
Protected

Academic year: 2021

Partager "Erreurs d'exécutions"

Copied!
9
0
0

Texte intégral

(1)

Licence Informatique - Semestre 6 - Compléments de Java

1

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

2

La gestion d’une exception

Une erreur qui lève une exception

Un contexte d’exécution

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

saut

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)

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é

(2)

Licence Informatique - Semestre 6 - Compléments de Java

3

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

RuntimeException

StackOverFlowErrorOutOfMemoryError VirtualMachineError

ClassNotFoundException AWTException

ArithmeticException NullPointerException

...

...

...

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.

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

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{

...

} }

public void static main(String[] args) throws FileNotFoundException{

MyClass.parseFile("MyFile");

}

(3)

Licence Informatique - Semestre 6 - Compléments de Java

5

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());

}

catch(ParseException e){

e.printStackTrace(System.out);

}

catch(IOException e){

System.out.println("Problème d'accés fichier");

} 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)

ExceptionTest2 ExceptionTest1

Licence Informatique - Semestre 6 - Compléments de Java

6

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);

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");}

} }

GroupeEtudiants

(4)

Licence Informatique - Semestre 6 - Compléments de Java

7

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

Instruction avec clause “finally”

Trouver la fin d’un flux est tout à fait normal, ce n’est pas une erreur!

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

try {

for (;;) process (stream.next());

}

catch(ExceptionType1 e){...}

...

finally{stream.close();}

try {

for (;;) process (stream.next());

}

catch(StreamEndException e){stream.close();}

(5)

Licence Informatique - Semestre 6 - Compléments de Java

9

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

10

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!)

(6)

Licence Informatique - Semestre 6 - Compléments de Java

11

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

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){

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){}

}

MyPoint

(7)

Licence Informatique - Semestre 6 - Compléments de Java

13

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

14

Types de clonage (1/2)

Objet A attribut1 attribut2

Objet B attribut3

Objet A' attribut1 attribut2

clonage de surface

Objet C attribut4

...

...

Objet A'' attribut1 attribut2

Objet B' attribut3

Objet C' attribut4

...

...

clonage en

profondeur

(8)

Licence Informatique - Semestre 6 - Compléments de Java

15

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();

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);

}

ShallowCopy

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)

(9)

Licence Informatique - Semestre 6 - Compléments de Java

17

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

18

Clonage et héritage (2/2)

Clonage et sérialisation : une sérialisation suivie d'une désérialisation est un clonage profond!!

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();

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);

}

DeepCopy

Références

Documents relatifs

Sans échelle (pour l’instant) on représente deux forces de même valeur, de direction verticale, et de sens opposés, appliquées l’une au centre de gravité du ballon

Une fois la réaction de synthèse de l’éthanoate de géranyle (E) terminée, c’est-à-dire lorsque les quantités de matière des réactifs et des produits n’évoluent plus,

Mais je me suis aussi inscrit en histoire, en philosophie (il y avait alors un certificat de sociologie qui accompagnait les études de philosophie), en science

Comme cette autonomie les amène à être seuls, sans aide humaine, ils doivent être « intelligents» pour fonctionner.. Ainsi, une voiture sans conducteur peut circuler seule, et un

Lire des textes variés avec des objectifs divers : étudier un recueil poétique Lire des œuvres littéraires, fréquenter des oeuvres d’art : l’objet dans les arts. Élaborer une

Cette méthode retourne vrai s’il existe une l’intersection ainsi que le point d’intersection faux, dans le cas contraire..  Une classe Droite constituée d’un Point et

En Java l’instanciation d’un objet se fait en deux étapes : 1 : Définition d’une variable du type de la classe désirée.. String uneChaine ; /* Déclare qu’il y aura un

Dans la première partie de l'année scolaire les élèves apprennent à identifier dans un problème les objets significatifs, à reconnaître a priori le type de données informatiques