Maîtriser les exceptions Java : Gérer les erreurs inattendues avec élégance
Une exception est un problème survenant pendant l'exécution d'un programme. Elle perturbe le flux normal et termine le programme anormalement, d'où la nécessité de la gérer.
Catégories d'exceptions
Exceptions vérifiées (Checked Exceptions)
Vérifiées par le compilateur à la compilation. Ne peuvent être ignorées ; le programmeur doit les gérer.
Exemple : FileNotFoundException si un fichier n'existe pas.
import java.io.File;
import java.io.FileReader;
public class FichierIntrouvableDemo {
public static void main(String args[]) {
File file = new File("E://fichier.txt");
FileReader fr = new FileReader(file); // Erreur de compilation si non gérée
}
}
Erreur de compilation :
FichierIntrouvableDemo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
Exceptions non vérifiées (Unchecked Exceptions / Runtime Exceptions)
Surviennent à l'exécution. Erreurs de programmation : logique incorrecte, mauvaise utilisation d'API. Ignorées à la compilation.
Exemple : ArrayIndexOutOfBoundsException.
public class ExceptionNonVerifieeDemo {
public static void main(String args[]) {
int num[] = {1, 2, 3, 4};
System.out.println(num[5]); // Index 5 inexistant
}
}
Résultat :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
Erreurs (Errors)
Problèmes graves hors contrôle du programmeur (ex: StackOverflowError, OutOfMemoryError). Généralement non gérés dans le code.
Hiérarchie des exceptions
Toutes les exceptions héritent de java.lang.Exception, qui hérite de Throwable. Error hérite aussi de Throwable.
Deux sous-classes principales d'Exception : IOException et RuntimeException.
Méthodes importantes de Throwable
| Méthode | Description |
|---|---|
getMessage() | Message détaillé de l'exception |
getCause() | Cause de l'exception (objet Throwable) |
toString() | Nom de la classe + message |
printStackTrace() | Affiche la pile d'appels sur System.err |
getStackTrace() | Tableau d'éléments de la pile (index 0 = sommet) |
fillInStackTrace() | Remplit la pile avec la trace courante |
Intercepter les exceptions (try-catch)
try {
// Code protégé
} catch (TypeException e) {
// Bloc de gestion
}
Exemple
public class TestException {
public static void main(String args[]) {
try {
int a[] = new int[2];
System.out.println("Accès élément 3 : " + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception levée : " + e);
}
System.out.println("Hors du bloc");
}
}
Résultat :
Exception levée : java.lang.ArrayIndexOutOfBoundsException: 3
Hors du bloc
Blocs catch multiples
try {
// Code protégé
} catch (ExceptionType1 e1) {
// Gestion type 1
} catch (ExceptionType2 e2) {
// Gestion type 2
}
Le premier bloc correspondant intercepte l'exception. Ordre important : du plus spécifique au plus général.
Capture multi-exceptions (Java 7+)
catch (IOException | FileNotFoundException ex) {
logger.log(ex);
throw ex;
}
Mots-clés throws / throw
- throws : déclare qu'une méthode peut lancer une exception vérifiée (report de la gestion)
- throw : lance explicitement une exception
Exemple throws
public void deposer(double montant) throws RemoteException {
// implémentation
throw new RemoteException();
}
Plusieurs exceptions
public void retirer(double montant) throws RemoteException, FondsInsuffisantsException {
// implémentation
}
Bloc finally
S'exécute toujours, qu'une exception se produise ou non. Idéal pour le nettoyage (fermeture de ressources).
try {
// Code protégé
} catch (ExceptionType1 e1) {
// Gestion
} finally {
// Nettoyage - toujours exécuté
}
Exemple
public class TestFinally {
public static void main(String args[]) {
int a[] = new int[2];
try {
System.out.println("Accès élément 3 : " + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception : " + e);
} finally {
a[0] = 6;
System.out.println("Premier élément : " + a[0]);
System.out.println("Bloc finally exécuté");
}
}
}
Résultat :
Exception : java.lang.ArrayIndexOutOfBoundsException: 3
Premier élément : 6
Bloc finally exécuté
try-with-resources (Java 7+)
Gestion automatique des ressources implémentant AutoCloseable. Fermeture garantie à la fin du bloc.
Syntaxe
try (FileReader fr = new FileReader("chemin/fichier")) {
// utilisation de la ressource
} catch (IOException e) {
// gestion
}
Exemple
import java.io.FileReader;
import java.io.IOException;
public class DemoTryWithResources {
public static void main(String args[]) {
try (FileReader fr = new FileReader("E://fichier.txt")) {
char[] a = new char[50];
fr.read(a);
for (char c : a) System.out.print(c);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Points clés :
- La classe doit implémenter
AutoCloseable - Plusieurs ressources possibles (fermées dans l'ordre inverse)
- Ressources implicitement
final
Exceptions personnalisées
Pour créer sa propre exception :
- Hériter de
Exceptionpour une exception vérifiée - Hériter de
RuntimeExceptionpour une exception d'exécution
Exemple : exception vérifiée
public class FondsInsuffisantsException extends Exception {
private double montant;
public FondsInsuffisantsException(double montant) {
this.montant = montant;
}
public double getMontant() {
return montant;
}
}
Utilisation
public class CompteVerif {
private double solde;
private int numero;
public CompteVerif(int numero) { this.numero = numero; }
public void deposer(double montant) { solde += montant; }
public void retirer(double montant) throws FondsInsuffisantsException {
if (montant <= solde) {
solde -= montant;
} else {
double manque = montant - solde;
throw new FondsInsuffisantsException(manque);
}
}
public double getSolde() { return solde; }
public int getNumero() { return numero; }
}
Test
public class DemoBanque {
public static void main(String[] args) {
CompteVerif c = new CompteVerif(101);
System.out.println("Dépôt 500€...");
c.deposer(500.00);
try {
System.out.println("Retrait 100€...");
c.retirer(100.00);
System.out.println("Retrait 600€...");
c.retirer(600.00);
} catch (FondsInsuffisantsException e) {
System.out.println("Manque " + e.getMontant() + "€");
e.printStackTrace();
}
}
}
Résultat :
Dépôt 500€...
Retrait 100€...
Retrait 600€...
Manque 200.0€
FondsInsuffisantsException at CompteVerif.retirer(CompteVerif.java:25)
at DemoBanque.main(DemoBanque.java:13)
Exceptions courantes
- Exceptions JVM :
NullPointerException,ArrayIndexOutOfBoundsException,ClassCastException - Exceptions programmatiques :
IllegalArgumentException,IllegalStateException
Java
- Maîtriser les opérateurs Java : Types, syntaxe et exemples pratiques
- Commentaires Java : Types, utilisation et bonnes pratiques
- Maîtriser la boucle for améliorée en Java : Syntaxe, exemples et bonnes pratiques
- Maîtriser les chaînes de caractères en Java : Création, méthodes et bonnes pratiques
- Maîtriser la gestion d'exceptions Java : try, catch, finally, throw et throws expliqués
- Java throw vs throws : maîtriser la gestion d'exceptions avec exemples pratiques
- Maîtriser la gestion multi-exceptions en Java
- Maîtriser le try-with-resources Java : gestion automatique des ressources expliquée
- Annotations Java expliquées : types, placement et exemples pratiques