PROGRAMMATION JAVA
Deuxième année Informatique (ENICARTHAGE)
1
GESTION DES EXCEPTIONS EN JAVA
2
// exemple
public class Salarie { import [Link];
private double salaire; import [Link];
public Salarie(double salaire) { public class Test {
[Link] = salaire; public static void main(String args[]){
} try {
public double getSalaire(){return salaire;} [Link]("Saisir votre salaire: ");
} Scanner clavier = new Scanner([Link]);
double salaire = [Link]();
// classe Test Salarie s = new Salarie(salaire);
import [Link]; [Link]("le salaire est " + salaire);
public class Test { }
public static void main(String args[]){ catch (InputMismatchException e)
[Link]("Saisir votre salaire: "); {
Scanner clavier = new Scanner([Link]); [Link]("Erreur : " + [Link]()+"
double salaire = [Link](); cause:"+[Link]());
Salarie s = new Salarie(salaire); }
[Link]("le salaire est " + salaire); [Link](-1); } }
si on saisit un type différent à celui de la méthode Saisir votre salaire:
appelée par le Scanner ? az
Il faut lever une exception qui est déjà existante : Erreur : null cause:null
InputMistchException
3
Si vous fournissez plusieurs blocs catch, ils devront alors être ordonnés du bloc le plus spécifique d’exception
au bloc le plus général, sinon vous aurez une erreur de compilation
// exemple:
try {
[Link]( "Veuillez saisir un entier : " );
Scanner clavier = new Scanner([Link]);
double salaire = [Link](); // l’entier inséré sera considéré comme chaine de caractères
int value = [Link]( strValue ); // convertir la chaine en entier
[Link]( "Value == " + value );
} catch( NumberFormatException e ) {
[Link]( "La chaîne ne correspond pas à un entier" ); // par la méthode parseInt
} catch( Exception e ) {
[Link]( "une exception quelconque" ); // tout type d’exception y compris celle du Scanner
}
4
// Même exemple avec création de notre exception
public class Salarie { public class Test {
private double salaire; public static void main(String args[]) {
public Salarie(double salaire) throws SalaireException { try {
if (salaire < 0) Salarie s = new Salarie(-1000.0);
// lever une exception [Link]("le salaire est " + [Link]());
throw (new SalaireException()); }
else [Link] = salaire; catch (SalaireException e) {
[Link]("Erreur : " + [Link]());
} }
public double getSalaire(){return salaire;} finally {
} [Link](-1);
}
}}
/* si on écrit [Link](-1) sans finally il ne sera exécuté
public class SalaireException extends Exception{
que dans le cas non exceptionnel*/
public SalaireException() {
super("le solde de votre compte est négatif");
}
}
Erreur : le solde de votre compte est négatif
5
// autre version de la classe Test
RQ: Un bloc catch peut également être
import [Link];
import [Link]; écrit pour intercepter plusieurs types
public class Test { d'exceptions spécifiques. Par exemple, le
public static void main(String args[]){ bloc catch suivant capture deux types
try { d'exception. Quand l'un ou l'autre est
attrapé, son identifiant local est e, et le
[Link]("Saisir votre salaire: "); traitement lui est appliqué
Scanner clavier = new Scanner([Link]);
double salaire = [Link]();
Salarie s = new Salarie(salaire);
[Link]("le salaire est " + salaire);
} Saisir votre salaire:
catch (SalaireException | InputMismatchException e) 3000
{ le salaire est 3000.0
[Link]("Erreur : " + Saisir votre salaire:
[Link]()+" cause:"+[Link]()); -2
} Erreur : le solde de votre compte est négatif cause:[Link]
[Link](-1); } } Saisir votre salaire:
az
Erreur : null cause:null
6
EXERCICE
Une équation de second degré dans IR s’écrit:
A.x2 + B.x + C = 0
Elle est définie par trois paramètres réels A, B et C.
Créer et tester la classe en développant essentiellement une méthode d’affichage
standard, et la méthode de résolution de l’équation
Pour le traitement des conditions une première solution classique provenant de la
programmation procédurale est un traitement dans la méthode
Une deuxième solution de la POO est de générer un objet d’exception
// solution classique public void setA(double A){this.A=A;}
public class Equation { public void setB(double B){this.B=B;}
private double A, B, C; public void setC(double C){this.C=C;}
public Equation(double A, double B, double C){ public double getA(){ return A;}
this.A=A; this.B=B; this.C= C;} public double getB(){ return B;}
public double getC(){ return C;}
@Override // Calcul DELTA
public String toString(){ public double getDelta(){
return(A+" x^2 + "+B+" x + "+C+" =0"); } return [Link](B,2)-4*A*C; }
7
// méthode de résolution
public void resoudre(){
double D = getDelta();
if(D>0) [Link]("solution 1 = "+(-B+[Link](D))/(2*A)+" solution 2 = "+(-[Link](D))/(2*A));
else if(D==0) [Link]("solution = "+(-B/(2*A)));
else [Link]("no solution");
} }
public class Test {
public static void main(String[] args) {
Equation eq = new Equation(-2,5.2,9);
[Link](eq);
[Link]();
}
}
-2.0 x^2 + 5.2 x + 9.0 =0
solution 1 = -1.1879710609249459 solution 2 = 3.7879710609249457
8
// solution Orientée Objet
// changement au niveau de la méthode resoudre
public void resoudre() throws ExceptionResolv{
double D = getDelta();
if(D>0) [Link]("solution 1 = "+(-B+[Link](D))/(2*A)+" solution 2 = "+(-[Link](D))/(2*A));
else if(D==0) [Link]("solution = "+(-B/(2*A)));
else throw (new ExceptionResolv()); }
// classe d’exception
public class ExceptionResolv extends Exception{
public ExceptionResolv(){
super("no solution");
} }
// classe principale
public class Test {
public static void main(String[] args) {
try{
Equation eq = new Equation(2,5.2,9);
[Link](eq);
[Link](); } 2.0 x^2 + 5.2 x + 9.0 =0
catch(ExceptionResolv er){ Erreur : no solution
[Link]("Erreur : " + [Link]()); }
}
} 9
NOTION D’EXCEPTION
Une exception est un événement exceptionnel risquant de compromettre le bon
déroulement du programme (Entrée utilisateur non valide, Échec d’un périphérique, Perte
de connexion réseau, Limites physiques (mémoire insuffisante), Erreurs de code, Ouvrir un
fichier indisponible, débordement tableau…)
Comme en C++, Java introduit un mécanisme traitant tous les cas exceptionnels et
permettant de séparer ces traitements des traitements habituels du programme.
Une exception sera représentée par un objet (donc modélisée par une classe) qui
contient la description du cas exceptionnel et d’un gestionnaire (bloc d’instruction
try/catch) qui peut déclencher lors d’une erreur ou anomalie ou cas exceptionnel la
transmission à l’endroit où l’on sait les traiter.
10
GESTION DE L’EXCEPTION
Exemple:
Cas normaux:
BEGIN main BEGIN main
BEGIN method1 BEGIN method1
BEGIN method2 BEGIN method2
Value == 1 Value == 0
END method2 END method2
END method1 END method1
END main END main
Problème: si divisor = 0
11
Soit la valeur calculée aléatoirement vaut 0 et dans ce cas une exception est déclenchée;
(on dit aussi que l'exception est levée
Le système se met à la recherche d'un gestionnaire d’exception (bloc de traitement d'erreur
try / catch): Dans notre cas un tel bloc n’existe pas dans la méthode method2. En
conséquence l'exécution de la méthode est interrompue, et on se retrouve en ligne 17.
Toutes les variables locales définis par method2 (ainsi que les éventuels paramètres de la
méthode) sont détruites (on a dépilé au niveau de la stack).
Nous sommes toujours en mode « exception levée » et donc le système cherche toujours à
localiser un bloc try / catch. Il n'y en a pas non plus dans la méthode method1, donc on
abandonne l'exécution de cette méthode et on dépile encore une fois. On se retrouve en
ligne 23.
Toujours pas de try / catch et du coup on sort de la méthode main.
Ainsi, le programme est terminé et La JVM a récupéré l'exception et elle l'affiche sur la
console mais sans la traiter. Le fait d'avoir suspendu l'exécution de toutes les méthodes
garanti qu'aucun affichage de type END methodX ne sera produit
12
TRAITEMENT D’EXCEPTION
Afin d’assurer le traitement de l’exception, un gestionnaire doit exister sous forme de
cette syntaxe: try {
// Bloc obligatoire d'instructions pouvant déclencher une erreur
} catch ( Exception exception ) {
// Bloc d'instructions pour traiter une éventuelle exception
} finally {
// Bloc d'instructions à exécuter dans tous les cas,
// que le try se soit exécuté en succès ou en erreur.
}
Nous pouvons aussi avoir une instruction try / finally sans bloc catch ou try/catch sans finally
13
La clause finally n’est pas obligatoire mais permet de spécifier le code qui sera exécuté
dans tous les cas (exception ou non)
Un bloc finally est généralement utilisé pour effectuer des opérations de conclusion
(fermeture de fichiers, de connexion réseau…)
L'utilisation des instructions break, continue, return ou throw (dans les blocs try ou catch)
n'empêche pas l'exécution préalable du bloc finally.
un bloc try doit obligatoirement être accompagné d'au moins un bloc catch ou d'un bloc
finally (ou des deux). Ces blocs peuvent être utilisés dans n’importe quelle méthode autre
que le main.
14
// exemple: try/finally sans catch Dans le cas exceptionnel:
public class Sample {
public static void main( String [] args ) { Exception in thread "main" [Link]: / by zero
at [Link]([Link])
try { On a terminé !
int randomValue = (int) ([Link]() * 3);
// Attention : une erreur en cas de division par 0
int res = 1 / randomValue;
[Link]( "Résultat == " + res );
} finally {
[Link]( "On a terminé !" );
}
}
15
HIÉRARCHIE DES EXCEPTIONS
16
CLASSE EXCEPTION
Pour créer notre propre classe d’Exception, nous devons créer une sous-classe de Exception
ou Error. Or, nous allons toujours créer nos propres exceptions pour les erreurs récupérables,
ces classes doivent alors hériter de la classe Exception
Il est classique de terminer chaque nom de sous-classe Exception par Exception.
La classe Exception contient quatre constructeurs:
Exception(String message) - Construit un nouvel objet Exception avec le message d’erreur
Exception() - Construit un nouvel objet Exception avec la valeur null comme message
d’erreur
Exception(String message, Throwable cause) – on donne un objet de l’une des sous classes
déjà existantes de Throwable qui a causé cette exception
Exception(Throwable cause) – le message est déterminé par [Link]() 17
Quelques méthodes de la classe Exception qu’on peut les redéfinir:
String getMessage() : retourne un String contenant le message associé à l'exception
String toString() : retourne un String contenant le nom de l'exception suivi du message
associé
Throwable getCause(): Renvoie la cause de l'exception représentée par un objet
Throwable.
StackTraceElement [] getStackTrace(): Retourne un tableau contenant chaque élément sur la
trace de la pile (liste des messages d'erreur après chaque tentative d'exécution)
Le mot-clé throws est utilisé dans la déclaration de méthode pour annoncer la liste des
exceptions que la méthode peut générer, tandis que le mot-clé throw est utilisé pour créer une
instance de l’exception,
Lorsque nous créons un segment de code dans lequel une erreur peut survenir, nous plaçons
le code dans un bloc try
Pour gérer une exception levée, nous pouvons coder un ou plusieurs blocs catch
immédiatement après un bloc try. Un bloc catch est un segment de code qui peut gérer une
exception peut être levée par le bloc try qui le précède
18
// exemple vu précédemment public class Test {
public class Salarie { public static void main(String args[]) {
private double salaire; try {
public Salarie(double salaire) throws SalaireException { Salarie s = new Salarie(-1000.0);
if (salaire < 0) [Link]("le salaire est " + [Link]());
// lever une exception }
throw (new SalaireException()); catch (SalaireException e) {
else [Link] = salaire; [Link]("Erreur : " + [Link]()+"
cause:"+ [Link]());
} }
public double getSalaire(){return salaire;} }}
}
public class SalaireException extends Exception{
public SalaireException() {
super("le solde de votre compte est négatif", new Exception());
}
}
Erreur : le solde de votre compte est négatif cause:[Link]
19
TRY-WITH-RESOURCES
syntaxe ajoutée à Java SE à partir de sa version 7.0, et améliorée avec la version
9.0: try (// ressources implémentant l’interface Autoclosable) {
// Bloc d'instructions
}
L’interface Autoclosable est fonctionnelle; elle comporte une seule méthode
abstraite close. Ainsi, toute classe concrète implémentant cette interface doit définir
sa méthode par forcer la fermeture de la ressource
Exemple 1:
// Cet exemple ne marche pas, car String n'implémente pas l'interface AutoCloseable.
try ( String demo = "Hello" ) {
[Link]( demo );
}
20
Exemple avec une seule ressource:
FileInputStream fis = new FileInputStream( "[Link]" );
// Une seule ressource automatiquement gérée
try ( fis ) { // Uniquement si Java SE >= 9.0
// Ici on manipule de fichier
} // Appel à la méthode close automatique
Exemple avec deux ressources:
// Deux ressources automatiquement gérées
try ( FileInputStream fis = new FileInputStream( "[Link]" ) ;
FileOutputStream fos = new FileOutputStream( "[Link]" ) ) {
// Ici on manipule nos deux fichiers (une copie de fichier, par exemple)
} // Appels aux méthodes close automatique
21
Exemple avec deux ressources + bloc catch
// Deux ressources automatiquement gérées, avec un bloc catch pour gérer les erreurs.
try ( FileInputStream fis = new FileInputStream( "[Link]" ) ;
FileOutputStream fos = new FileOutputStream( "[Link]" ) ) {
// Ici on manipule nos deux fichiers (une copie de fichier, par exemple)
} catch( IOException exception ) {
// Il y a donc eu une erreur durant la copie des fichiers
[Link]( "Impossible de réaliser la copie du fichier" );
} catch( SecurityException exception ) {
// On a un problème de droits sur les fichiers ([Link])
[Link]( "Vous n'avez pas les droits pour réaliser la copie du fichier" );
}// fermeture des fichiers par close
22