1. La classe Throwable : la racine de toutes les exceptions
Nous allons maintenant examiner en détail le fonctionnement du système d’exceptions en Java : ce qu’est Throwable, en quoi Exception et Error diffèrent, et ce que signifient « vérifiée » et « non vérifiée » pour une exception. C’est le fondement d’une bonne gestion des erreurs dans vos programmes.
En Java, toutes les exceptions et erreurs sont des objets qui héritent de la classe java.lang.Throwable.
Throwable est « l’ancêtre » de toute la hiérarchie de gestion des problèmes en Java.
Schématiquement :
Throwable
├── Exception
└── Error
Throwable est la classe de base pour tout ce qui peut être « lancé » (throw) et « intercepté » (catch) en Java. On ne l’utilise pas directement — il sert de base à des types d’erreurs plus concrets.
Exception — pour les erreurs « normales »
Exception est la classe de base pour toutes les exceptions susceptibles de se produire dans un programme et qu’il faut et qu’on peut traiter. Ce sont des erreurs « opérationnelles » : problèmes de fichiers, réseau, E/S, erreurs utilisateur, etc. La plupart de vos try-catch travailleront justement avec des sous-classes d’Exception.
Exemples :
- IOException — erreur lors de la manipulation de fichiers ou du réseau.
- SQLException — erreur lors de l’accès à la base de données.
- FileNotFoundException — fichier introuvable.
Error — pour les erreurs fatales de la JVM
Error est la classe de base des erreurs qui se produisent au niveau de la machine virtuelle Java (JVM). Ce sont généralement des défaillances critiques que le programme ne peut ni ne doit traiter. Si un Error survient, l’application ne pourra probablement pas continuer à s’exécuter.
Exemples :
- OutOfMemoryError — mémoire insuffisante.
- StackOverflowError — dépassement de pile (par exemple à cause d’une récursion infinie).
- NoClassDefFoundError — classe requise introuvable.
Important :
Intercepter et traiter Error est presque toujours une mauvaise idée. Ce ne sont pas des erreurs de votre programme, mais des défaillances de l’environnement d’exécution.
2. Exceptions vérifiées (checked) vs non vérifiées (unchecked) : qu’est‑ce que cela signifie ?
En Java, toutes les exceptions se répartissent en deux grandes catégories :
Exceptions vérifiées (Checked)
Qu’est‑ce que c’est ? Des exceptions que le compilateur oblige à traiter ou à relancer explicitement.
Quand surviennent‑elles ? Généralement liées à des ressources externes : fichiers, réseau, bases de données, saisie utilisateur.
Comment les traiter ? Il faut soit entourer le code d’un try-catch, soit ajouter throws à la signature de la méthode.
Exemples : IOException, SQLException, FileNotFoundException
Exemple :
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // peut lancer IOException
// ...
}
Si vous ne les traitez pas ou ne les relancez pas — le programme ne compilera pas !
Exceptions non vérifiées (Unchecked)
Qu’est‑ce que c’est ? Des exceptions qui ne nécessitent pas de traitement obligatoire par le compilateur.
Quand surviennent‑elles ? Il s’agit généralement d’erreurs de logique du programme : division par zéro, dépassement des limites d’un tableau, accès à null.
Comment les traiter ? On peut les intercepter, mais ce n’est pas obligatoire. Il vaut mieux les prévenir grâce à des vérifications.
Où dans la hiérarchie ? Elles héritent toutes de RuntimeException.
Exemples : NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, ArithmeticException
Exemple :
int[] arr = {1, 2, 3};
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException
Le compilateur ne vous oblige pas à intercepter cette exception — mais le programme « plantera » en cas d’erreur.
3. Toute la hiérarchie en un seul schéma
graph TD
Throwable --> Error
Throwable --> Exception
Exception --> RuntimeException
Exception --> CheckedExceptions["(autres exceptions vérifiées)"]
Error --> OutOfMemoryError
Error --> StackOverflowError
RuntimeException --> NullPointerException
RuntimeException --> IndexOutOfBoundsException
RuntimeException --> IllegalArgumentException
%% Styles
style Throwable fill:#ffa64d,color:#000
style Exception fill:#ffa64d,color:#000
style CheckedExceptions fill:#ffa64d,color:#000
style Error fill:#ff4d4d,color:#fff
style OutOfMemoryError fill:#ff4d4d,color:#fff
style StackOverflowError fill:#ff4d4d,color:#fff
style RuntimeException fill:#4dff88,color:#000
style NullPointerException fill:#4dff88,color:#000
style IndexOutOfBoundsException fill:#4dff88,color:#000
style IllegalArgumentException fill:#4dff88,color:#000
Tableau: principales différences
| Groupe | Classe parente | Nécessite un traitement ? | Exemples |
|---|---|---|---|
| Exception vérifiée | |
Oui | |
| Non vérifiée | |
Non | |
| Error | |
Non | |
4. À quoi cela ressemble-t-il dans le code ?
Exception vérifiée : exemple avec des fichiers
import java.io.*;
public class FileDemo {
public static void main(String[] args) {
try {
FileReader reader = new FileReader("nofile.txt"); // FileNotFoundException (checked)
int data = reader.read();
System.out.println(data);
reader.close();
} catch (IOException e) {
System.out.println("Erreur lors de la manipulation du fichier : " + e.getMessage());
}
}
}
Le compilateur vous obligera à traiter IOException !
Exception non vérifiée : exemple de division par zéro
public class ExceptionDemo {
public static void main(String[] args) {
int a = 10;
int b = 0;
int c = a / b; // ArithmeticException (unchecked)
System.out.println("Résultat : " + c);
}
}
Le compilateur ne demande aucun traitement, mais le programme « plantera ».
5. À quoi sert la hiérarchie des exceptions ?
- Souplesse du traitement : vous pouvez intercepter des erreurs spécifiques (FileNotFoundException) comme des groupes entiers (IOException ou Exception).
- Réutilisation du code : possibilité de traiter de façon centralisée les erreurs d’un même type.
- Propreté du code : la logique principale n’est pas encombrée de vérifications pour chaque détail.
Exemple :
try {
// code risqué
} catch (FileNotFoundException e) {
System.out.println("Fichier introuvable !");
} catch (IOException e) {
System.out.println("Erreur d’entrée/sortie !");
} catch (Exception e) {
System.out.println("Quelque chose s’est mal passé : " + e.getMessage());
}
6. Erreurs typiques lors de la gestion des exceptions
Erreur № 1: ignorer les exceptions. Écrire catch (Exception e) {} — c’est mauvais ! Vous perdez des informations sur la cause de l’erreur.
Erreur № 2: intercepter trop large. catch (Exception e) intercepte tout, même ce à quoi vous ne vous attendiez pas. Mieux vaut n’intercepter que les exceptions que vous savez traiter.
Erreur № 3: intercepter des erreurs (Error). Évitez d’intercepter Error, sauf si vous écrivez du code bas niveau. Ce sont des problèmes de la JVM, pas de votre programme.
Erreur № 4: ne pas distinguer checked et unchecked. Toutes les exceptions ne sont pas identiques ! Les checked exigent un traitement (Exception), les unchecked — non (RuntimeException et ses sous-classes).
Erreur № 5: ne pas enrichir les exceptions. Si vous créez vos propres exceptions — ajoutez toujours un message informatif.
GO TO FULL VERSION