Ce dixième chapitre aborde le traitement des exceptions.
Le premier exercice s'intéresse à la saisie d'un entier par un utilisateur dans une boîte de dialogue. Le deuxième exercice concerne la division par zéro illustrant la création de nouvelles exceptions. Le troisième exercice montre le fonctionnement des exceptions. Le dernier exercice porte sur la saisie de longueurs appliquée à la saisie de ses dimensions.
Les principales notions abordées sont les suivantes :
Bloc try / Catch ;
Lancer une exception (throw) ;
Capturer une exception (catch) ;
Bloc Finally ;
Clause throws ;
Créer des exceptions personnalisées ;
Pile d'appels de méthodes (printStackTrace).
Pour faire et comprendre ces exercices, vous aurez besoin d'un certain nombre de notions sur le langage Java en rapport avec le chapitre. Pour cela, vous pouvez consulter les tutoriels Java de developpez à l'adresse suivante : https://java.developpez.com/cours/Cours en Java
Écrivez une application qui demande à l'utilisateur de saisir un entier à l'aide d'une boîte de dialogue. Tant que la valeur saisie est incorrecte, affichez un message d'erreur et demandez à nouveau la saisie. Si la valeur est correcte, affichez un message de confirmation. Note : Utilisez un bloc try / catch avec l'exception NumberFormatException.
Note : javaws -viewer (accessible également depuis le panneau de configuration Java) permet de voir les différentes applications JWS en cache et de les gérer.
/* * Fichier: SaisieEntier.java * Crée le: 21 juin 2007. * Modifié: 21 février 2009. * Auteurs: Sébastien ESTIENNE. * SiteWeb: http://www.prog-info.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package chapitre10;
import javax.swing.JOptionPane;
/** * <p>Classe illustrant le principe des exceptions par la saisie d'un entier.</p> * @author Sébastien ESTIENNE. */publicclass SaisieEntier
{/** * <p>Lance l'application.</p> * @param argsLes paramètres de la ligne de commande. */publicstaticvoidmain(String[] args)
{// Indique si la valeur saisie est valide ou non.boolean estValide =false;
// La valeur de l'entier saisi.int entier =0;
// Demande un entier à l'utilisateur tant que la saisie est invalide.
String sEntier =null;
while(!estValide)
{// Demande la saisie d'un entier et essai de le convertir.
sEntier = JOptionPane.showInputDialog(null, "Saisissez un entier : ", "Entier",
JOptionPane.QUESTION_MESSAGE);
try{
entier = Integer.parseInt(sEntier);
estValide =true;
}// Affiche un message d'erreur si la saisie n'est pas un entier.catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null, "La valeur saisie n'est pas un entier.", "Erreur",
JOptionPane.ERROR_MESSAGE);
}}// Affiche le résultat.
JOptionPane.showMessageDialog(null, "Vous avez saisi l'entier : "+ entier, "Résultat",
JOptionPane.INFORMATION_MESSAGE);
}}
Écrivez un programme contenant une classe d'exception de division par zéro héritant de la classe ArithmeticException ainsi qu'une classe permettant de tester cette exception.
Cette classe de test est une application graphique contenant des étiquettes et des champs pour le numérateur, le dénominateur et le quotient. Le programme doit afficher un message d'erreur lorsqu'une des valeurs saisies n'est pas un entier ou encore lorsque le dénominateur vaut zéro.
Note : javaws -viewer (accessible également depuis le panneau de configuration Java) permet de voir les différentes applications JWS en cache et de les gérer.
/* * Fichier: DivisionParZeroException.java * Crée le: 21 juin 2007. * Modifié: 7 juillet 2007. * Auteurs: Sébastien ESTIENNE. * SiteWeb: http://www.prog-info.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package chapitre10.division;
/** * <p>Classe d'exception pour la division par zéro.</p> * @author Sébastien ESTIENNE. */publicclass DivisionParZeroException extends ArithmeticException
{/** * <p>Serial version UID.</p> */privatestaticfinallong serialVersionUID =1L;
/** * <p>Constructeur spécifiant une exception pour la division par zéro avec un message d'erreur * par défaut.</p> */publicDivisionParZeroException()
{super("Tentative de division par zéro !");
}/** * <p>>Constructeur spécifiant une exception pour la division par zéro avec le message d'erreur * défini.</p> * @param messageLe message d'erreur de l'exception. */publicDivisionParZeroException(String message)
{super(message);
}}
/* * Fichier: DivisionParZero.java * Crée le: 21 juin 2007. * Modifié: 7 juillet 2007. * Auteurs: Sébastien ESTIENNE. * SiteWeb: http://www.prog-info.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package chapitre10.division;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
/** * <p>Classe permettant de tester l'exception de division par zéro.</p> * @author Sébastien ESTIENNE. */publicclass DivisionParZero extends JFrame implements ActionListener
{/** * <p>Serial version UID.</p> */privatestaticfinallong serialVersionUID =1L;
/** Etiquette pour le numérateur. */private JLabel etiquetteNumerateur;
/** Etiquette pour le dénominateur. */private JLabel etiquetteDenominateur;
/** Etiquette pour le résultat. */private JLabel etiquetteResultat;
/** Champ texte pour le numérateur. */private JTextField champNumerateur;
/** Champ texte pour le dénominateur. */private JTextField champDenominateur;
/** Champ texte pour le résultat. */private JTextField champResultat;
/** * <p>Construction de l'application.</p> */publicDivisionParZero()
{// Appel du constructeur de la classe JFrame.super("Division par zéro");
// Obtenir le panneau de contenu et changer son layout en un GridLayout.
Container conteneur =getContentPane();
conteneur.setLayout(newGridLayout(3, 2, 5, 5));
// Initialisation des composants de l'interface graphique.this.etiquetteNumerateur =newJLabel("Numérateur :");
conteneur.add(this.etiquetteNumerateur);
this.champNumerateur =newJTextField();
conteneur.add(this.champNumerateur);
this.etiquetteDenominateur =newJLabel("Dénominateur :");
conteneur.add(this.etiquetteDenominateur);
this.champDenominateur =newJTextField();
conteneur.add(this.champDenominateur);
this.champDenominateur.addActionListener(this);
this.etiquetteResultat =newJLabel("Résultat :");
conteneur.add(this.etiquetteResultat);
this.champResultat =newJTextField();
this.champResultat.setEditable(false);
conteneur.add(this.champResultat);
// Modifie les propriétés de la fenêtre.setSize(260, 110);
setLocation(100, 100);
setVisible(true);
}/** * <p>Traite une demande de calcul de quotient (résultat).</p> * @param actionEventUn événement sémantique qui indique qu'une action s'est produite dans le * composant concerné. */publicvoidactionPerformed(ActionEvent actionEvent)
{// Efface le champ résultat.this.champResultat.setText("");
// Format du champ résultat.
DecimalFormat precision =newDecimalFormat("0.000");
// Essaie de récupérer les valeurs saisies et de calculer le quotient.try{int numerateur = Integer.parseInt(this.champNumerateur.getText());
int denominateur = Integer.parseInt(this.champDenominateur.getText());
double resultat =quotient(numerateur, denominateur);
this.champResultat.setText(precision.format(resultat));
}// Traite une erreur de format.catch(NumberFormatException nfe)
{
JOptionPane.showMessageDialog(this,
"Le numérateur et le dénominateur doivent être des nombres entiers.",
"Erreur de format", JOptionPane.ERROR_MESSAGE);
}// Traite une erreur de division par zéro.catch(DivisionParZeroException dpze)
{
JOptionPane.showMessageDialog(this, dpze.getMessage(), "Erreur de division",
JOptionPane.ERROR_MESSAGE);
}}/** * <p>Effectue la division.</p> * @param pNumerateurLe numérateur. * @param pDenominateurLe dénominateur. * @return Le résultat de la division. * @throws DivisionParZeroExceptionLance une exception lorsque le dénominateur vaut zéro. */publicdoublequotient(int pNumerateur, int pDenominateur) throws DivisionParZeroException
{if(pDenominateur ==0)
{thrownewDivisionParZeroException();
}return(double) pNumerateur / pDenominateur;
}/** * <p>Lance l'application.</p> * @param argsLes paramètres de la ligne de commande. */publicstaticvoidmain(String[] args)
{newDivisionParZero();
}}
Écrivez une classe permettant d'illustrer le fonctionnement du bloc try / catch / finally.
Cette classe contient deux méthodes, une qui lance une exception et l'autre qui ne lance pas d'exception. Ces deux méthodes contiennent un bloc try / catch / finally ne faisant qu'afficher des messages de traces.
Note : javaws -viewer (accessible également depuis le panneau de configuration Java) permet de voir les différentes applications JWS en cache et de les gérer.
/* * Fichier: FonctionnementException.java * Crée le: 23 juin 2007. * Modifié: 21 février 2009. * Auteurs: Sébastien ESTIENNE. * SiteWeb: http://www.prog-info.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package chapitre10;
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/** * <p>Classe montrant le fonctionnement des exceptions.</p> * @author Sébastien ESTIENNE. */publicclass FonctionnementExceptions extends JFrame
{/** * <p>Serial version UID.</p> */privatestaticfinallong serialVersionUID =1L;
/** Zone de sortie. */private JTextArea zoneSortie =null;
/** * <p>Construction de l'application.</p> */publicFonctionnementExceptions()
{// Appel du constructeur de la classe JFrame.super("Fonctionnement Exceptions");
// Obtenir le panneau de contenu et changer son layout en un BorderLayout.
Container conteneur =getContentPane();
conteneur.setLayout(newBorderLayout());
// Initialisation des composants de l'interface graphique.this.zoneSortie =newJTextArea();
conteneur.add(newJScrollPane(this.zoneSortie));
// Test de la méthode lancerException.try{lancerException();
}catch(Exception e)
{this.zoneSortie.append("main : Exception capturée dans le bloc catch.\n");
}// Test de la méthode nePasLancerException.this.zoneSortie.append("\n");
nePasLancerException();
// Modifie les propriétés de la fenêtre.setSize(400, 200);
setLocation(100, 100);
setVisible(true);
}/** * <p>Méthode permettant d'illustrer le concept try/catch/finally et simulant le lancement d'une * exception.</p> * @throws ExceptionL'exception lancée. */publicvoidlancerException() throws Exception
{// Début de la méthode.this.zoneSortie.append("lancerException : Début de la méthode.\n");
// Lance une exception.try{this.zoneSortie.append("lancerException : Passage dans le bloc try.\n");
thrownewException();
}// Capture l'exception et la relance.catch(Exception e)
{this.zoneSortie.append("lancerException : Exception capturée dans le bloc catch.\n");
throw e;
}// Code exécuté qu'une exception soit lancée ou non.finally{this.zoneSortie.append("lancerException : Passage dans le bloc finally.\n");
}// Code inaccessible.// this.zoneSortie.append("lancerException : Fin de la méthode.\n");}/** * <p>Méthode permettant d'illustrer le concept try/catch/finally et qui ne lève pas * d'exception.</p> */publicvoidnePasLancerException()
{// Début de la méthode.this.zoneSortie.append("nePasLancerException : Début de la méthode.\n");
// Entrée dans le bloc try.try{this.zoneSortie.append("nePasLancerException : Entrée dans le bloc try.\n");
}// Ce bloc ne s'exécute pas, car aucune exception n'est levée.catch(Exception e)
{this.zoneSortie.append("nePasLancerException : Mince on est dans le bloc catch!\n");
this.zoneSortie.append(e.toString());
}// Code exécuté qu'une exception soit lancée ou non.finally{this.zoneSortie.append("nePasLancerException : Passage dans le bloc finally.\n");
}// Fin de la méthode.this.zoneSortie.append("nePasLancerException : Fin de la méthode.\n");
}/** * <p>Lance l'application.</p> * @param argsLes paramètres de la ligne de commande. */publicstaticvoidmain(String[] args)
{newFonctionnementExceptions();
}}
Écrivez un programme contenant une classe d'exception de longueur négative héritant de la classe ArithmeticException ainsi qu'une classe permettant de tester cette exception.
Cette classe de test est une application graphique qui contient une zone de texte pour afficher les messages. Elle contient une méthode permettant la saisie d'une valeur de longueur. La saisie est redemandée jusqu'à ce que celle-ci soit valide. Une boîte de dialogue d'erreur et une trace (printStackTrace) sont affichées lorsque la valeur saisie n'est ni un entier ni une valeur positive.
Utilisez cette fonction pour demander la saisie de la longueur et de la largeur d'un rectangle pour afficher ensuite les informations saisies et l'aire du rectangle.
Note : javaws -viewer (accessible également depuis le panneau de configuration Java) permet de voir les différentes applications JWS en cache et de les gérer.
/* * Fichier: LongueurNegativeException.java * Crée le: 23 juin 2007. * Modifié: 7 juillet 2007. * Auteurs: Sébastien ESTIENNE. * SiteWeb: http://www.prog-info.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package chapitre10.rectangle;
/** * <p>Classe d'exception pour une valeur de longueur négative.</p> * @author Sébastien ESTIENNE. */publicclass LongueurNegativeException extends ArithmeticException
{/** * <p>Serial version UID.</p> */privatestaticfinallong serialVersionUID =1L;
/** * <p>Constructeur spécifiant une exception pour une longueur négative avec un message d'erreur * par défaut.</p> */publicLongueurNegativeException()
{super("Une valeur de longueur ne peut être négative!");
}/** * <p>>Constructeur spécifiant une exception pour une longueur négative avec le message d'erreur * défini.</p> * @param messageLe message d'erreur de l'exception. */publicLongueurNegativeException(String message)
{super(message);
}}
/* * Fichier: SaisieRectangle.java * Crée le: 23 juin 2007. * Modifié: 21 février 2009. * Auteurs: Sébastien ESTIENNE. * SiteWeb: http://www.prog-info.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package chapitre10.rectangle;
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/** * <p>Classe permettant de saisir les informations d'un rectangle.</p> * @author Sébastien ESTIENNE. */publicclass SaisieRectangle extends JFrame
{/** * <p>Serial version UID.</p> */privatestaticfinallong serialVersionUID =1L;
/** Zone de sortie. */private JTextArea zoneSortie;
/** * <p>Construction de l'application.</p> */publicSaisieRectangle()
{// Appel du constructeur de la classe JFrame.super("Saisie rectangle");
// Obtenir le panneau de contenu et changer son layout en un GridLayout.
Container conteneur =getContentPane();
conteneur.setLayout(newBorderLayout());
// Initialisation des composants de l'interface graphique.this.zoneSortie =newJTextArea();
this.zoneSortie.setEditable(false);
conteneur.add(newJScrollPane(this.zoneSortie));
// Modifie les propriétés de la fenêtre.setSize(400, 200);
setLocation(100, 100);
setVisible(true);
// Demande les informations du rectangle.int longueur =demanderDimension("Saisissez la longueur du rectangle :");
int largeur =demanderDimension("Saisissez la largeur du rectangle :");
this.zoneSortie.append("Longueur du rectangle : "+ longueur +"\n");
this.zoneSortie.append("Largeur du rectangle : "+ largeur +"\n");
this.zoneSortie.append("Aire du rectangle : "+(longueur * largeur));
}/** * <p>Demande une valeur de dimension à l'utilisateur.</p> * @param messageLe message de demande. * @return Retourne la valeur de la dimension saisie. */publicintdemanderDimension(String message)
{// Indique si la valeur saisie est valide ou non.boolean estValide =false;
// La valeur de la longueur;int longueur =0;
// Demande une valeur de longueur à l'utilisateur tant que la saisie est invalide.
String sDimension =null;
while(!estValide)
{// Demande la saisie d'une longueur et essaie de le convertir.
sDimension = JOptionPane.showInputDialog(null, message, "Saisie longueur",
JOptionPane.QUESTION_MESSAGE);
// Essaie de convertir la valeur saisie.try{
longueur = Integer.parseInt(sDimension);
if(longueur <0)
{thrownewLongueurNegativeException();
}
estValide =true;
}// Affiche un message d'erreur si la saisie n'est pas un entier.catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null, "La valeur saisie n'est pas un entier.", "Erreur",
JOptionPane.ERROR_MESSAGE);
this.zoneSortie.append(e.getMessage() +"\n");
StackTraceElement[] elements = e.getStackTrace();
for(StackTraceElement elem : elements)
{this.zoneSortie.append(elem.toString() +"\n");
}this.zoneSortie.append("\n");
}// Affiche un message d'erreur si l'entier n'est pas positif.catch(LongueurNegativeException e)
{
JOptionPane.showMessageDialog(null, "Une valeur de longueur ne peut être négative.",
"Erreur", JOptionPane.ERROR_MESSAGE);
this.zoneSortie.append(e.getMessage() +"\n");
StackTraceElement[] elements = e.getStackTrace();
for(StackTraceElement elem : elements)
{this.zoneSortie.append(elem.toString() +"\n");
}this.zoneSortie.append("\n");
}}return longueur;
}/** * <p>Lance l'application.</p> * @param argsLes paramètres de la ligne de commande. */publicstaticvoidmain(String[] args)
{newSaisieRectangle();
}}
Je tiens à remercier christopheJ, Baptiste Wicht, eusebe19 et jacques_jean pour les conseils, remarques et relectures.
Je remercie aussi www.developpez.com me permettant de publier cet article et Nono40 pour ses outils.
Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants :