Accueil > Programmer avec Java >
try
et catch
Exception
qui permet de gérer ces événements en fournissant des informations sur l’erreur qui s’est produite.try
et catch
try
contient le code qui pourrait générer une exception, et le bloc catch
contient le code qui gère l’exception si elle se produit.throws
À la fin de cette leçon vous devrez être en mesure de :
try
et catch
pour gérer les exceptions.try
et catch
.En génie logicielle, il y a un principe qui s’appelle la responsabilité unique. Ce principe nous dit que chaque méthode doit être responsable d’une seule chose. C’est une des raisons pourquoi nous brisons nos algorithmes en méthodes plus petites : cela limite la responsabilité de main
à l’organisation globale des opérations et permet à chaque méthode d’avoir un objectif clair.
Si on utilise du code qui peut générer une exception, on a deux choix :
throws Exception
à la signature de la méthode pour passer la gestion de l’exception à la méthode appelante, outry
et catch
pour gérer l’exception dans la méthode directement.La deuxième option est préférable selon le principe de responsabilité unique, car la méthode gère les problèmes potentiels avec le code qu’il utilise pour accomplir sa tâche, et les autres méthodes n’ont pas besoin de s’en soucier : elles peuvent se concentrer sur leur propre tâche.
try
et catch
pour des entrées invalidesLe bloc try
contient le code qui peut lancer une exception, et le bloc catch
contient le code à faire si une exception est lancée. Voici la structure de base d’un bloc try
et catch
:
1
2
3
4
5
try {
// code qui pourrait lancer une exception
} catch (Exception e) {
// code à exécuter si une exception est lancée
}
Voici un exemple de code1 qui lance une exception si l’utilisateur entre un texte qui ne peut pas être converti en un nombre entier. Dans cet exemple, on ne laisse pas le programme planter, mais on demande à l’utilisateur de réessayer :
Fichier:
ExceptionExample.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.*;
Scanner input = new Scanner(System.in);
int getInt(String prompt) {
// tentatives infinies jusqu'à ce que tout dans le try fonctionne
while (true) {
try {
System.out.print(prompt);
int number = input.nextInt(); // peut planter
return number; // quitte la méthode si tout va bien
} catch (Exception e) { // si ça plante
System.out.println(" Entrée invalide");
input.next(); // vide l'entrée invalide du Scanner
}
}
}
void main() {
int age = getInt("Entrez votre âge : "); // pas besoin de savoir que ça peut planter
System.out.println("Vous avez soumis un âge de : " + age);
}
Notez que dans main
on veut simplement obtenir un nombre entier et l’utiliser. Cela est possible parce que la méthode getInt
gère les exceptions qui pourraient survenir lors de la conversion de l’entrée utilisateur en un nombre entier. Ainsi, chaque méthode s’occupe de sa propre responsabilité et n’a pas besoin de connaître les détails internes des autres méthodes. C’est un bon exemple de la responsabilité unique.
Voici une autre version de main
1 pour ce même problème, mais dans ce cas-ci, main
gère une autre sorte d’entrée invalide : une entrée qui n’est pas un âge valide. Ce type d’erreur ne cause pas d’exception, mais pourrait causer des erreurs de logique dans le programme.
1
2
3
4
5
6
7
8
void main() {
int age = getInt("Entrez votre âge : ");
if (age < 0) { // gérer une valeur logiquement invalide
System.out.println("Âge invalide");
} else {
System.out.println("Vous avez soumis un âge de : " + age);
}
}
try
et catch
pour des ressources comme des fichiersNous étudions les fichiers en plus de détail dans la dernière section de cette unité
Si le programme génère une exception lors de l’utilisation d’une ressource comme un fichier, il est important de fermer la ressource avant de quitter le programme. Pour cela, on utilise une déclaration try
avec une ressource. Dans cette version de la structure, la ressource est déclarée dans les parenthèses après le mot-clé try
. La ressource est automatiquement fermée par Java à la fin du bloc try
, même si une exception est lancée.
Voici la structure d’une déclaration try-catch quand le plantage est lié à la ressource utilisée :
1
2
3
4
5
try ( déclaration de la ressource qui peut planter ) {
// code à exécuter avec la ressource si ça ne plante pas
} catch (Exception e) {
// code à exécuter si ça plante
}
Voici un exemple où la ressource qui peut planter est un FileWriter
pour écrire dans un fichier.
1
2
3
4
5
6
7
void writeMessageToFile(String message) {
try (FileWriter output = new FileWriter("./data/output.txt")) {
output.write(message);
} catch (Exception e) {
System.out.println("Chemin de fichier invalide");
}
}
Voici un deuxième exemple où la ressource qui peut planter est l’objet File
qu’on passe au Scanner
pour extraire son contenu.
1
2
3
4
5
6
7
8
9
10
String getFileContents(Locale decimalFormat) {
try (Scanner fileReader = new Scanner(new File("./data/input.txt"))) {
fileReader.useLocale(decimalFormat);
fileReader.useDelimiter("\\Z"); // next() s'arrête au caractère de fin de fichier
return fileReader.next();
} catch (Exception e) {
System.out.println("Fichier introuvable");
return null; // quittez la méthode avec une référence `null` pour le String
}
}
Notez que dans ces deux exemples, on doit déclarer et initialiser la ressource plantable entre des parenthèses après le mot-clé try
.
Pour ce cours, c’est tout à fait normal d’utiliser Exception
- la plus générale de toutes les exceptions - comme type d’exception dans le bloc catch
. Mais en situation de production logicielle, c’est important de déclarer l’exception spécifique qui peut survenir dans le bloc catch
.
Par exemple :
InputMismatchException
(avec les méthodes de Scanner nextInt et nextDouble) ou NumberFormatException
(si on utilise plutôt Integer.parseInt(input.next()) ou Double.parseDouble(input.next())). Ce sont des exceptions pour les erreurs de conversion de chaînes de caractères en nombres.IOException
.Utiliser une exception spécifique permet de gérer les exceptions de manière plus précise. En fait, cette structure nous permet de déclarer un bloc catch
pour chaque type d’exception qui peut survenir. Le premier bloc catch
qui correspond à l’exception lancée est celui qui est exécuté, comme une cascade if-else if, alors c’est important de les mettre dans l’ordre du plus spécifique (p. ex. IOException
) au plus général (Exception
).
aucun quiz de vérification des concepts ici encore
Travaillez dans le répertoire GitHub partagé par votre enseignant pour la pratique et les exercices
ExceptionExample.java
et le tester.double getDouble(String prompt)
qui fonctionne de la même manière que getInt
, mais pour les nombres à virgule flottante et ajouter une utilisation de cette méthode dans main
.System.out.println("Entrée invalide");
dans les blocs catch avec e.printStackTrace();
pour voir le message d’erreur complet sans toutefois faire planter le programme. Notez le type d’exception qui est lancée (celui qui s’affiche en premier dans le message d’erreur).