
FAQ Langage JavaConsultez toutes les FAQ
Nombre d'auteurs : 42, nombre de questions : 297, derni�re mise � jour : 19 septembre 2017 Ajouter une question
Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur le forum Java de http://java.developpez.com ainsi que l'exp�rience personnelle des auteurs.
Nous tenons � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant r�dacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture.
- Quels sont les principaux types d'exceptions ?
- Comment lancer ou d�clencher une exception ?
- Comment capturer ou attraper une exception ?
- Comment capturer plus d'une exception ?
- � quoi sert le mot-cl� finally pour le traitement d'une exception ?
- Qu'est-ce que try-with-resources ?
- Comment d�finir la cause d'une exception ?
- Que sont les exceptions supprim�es ?
- Comment ajouter des exceptions supprim�es dans une exception ?
- Comment �viter les null et NullPointerException tout en gardant son code �l�gant ?
En Java, il existe trois grandes cat�gories d'exceptions et d'erreurs.
Checked exception
Ce genre d'exception d�crit une erreur que votre programme doit savoir traiter et g�rer�; elles sont d�clar�es sur les m�thodes qui peuvent les g�n�rer lorsqu'elles doivent faire remonter des erreurs. Par exemple, si vous demandez l'ouverture en lecture d'un fichier qui n'existe pas, une checked exception de type java.io.FileNotFoundException sera g�n�r�e lorsque votre code s�ex�cutera. En attrapant cette erreur, vous pouvez en informer l'utilisateur de votre programme. Lors de la compilation, le compilateur va v�rifier que les exceptions de ce genre sont bien d�clar�es dans la signature des m�thodes qui sont susceptibles de les g�n�rer et vous sugg�rer soit de les traiter dans le corps des m�thodes appelantes, soit de les d�clarer dans leur signature pour les faire remonter � un niveau plus �lev�. Ces exceptions h�ritent de la classe java.lang.Exception et ce sont celles que vous serez le plus souvent amen� � manipuler et �galement � impl�menter.
Quelques exemples�:
- java.io.IOException - la classe parente de toutes les exceptions li�es aux manipulations en lecture/�criture de fichiers et de flux�;
- java.io.FileNotFoundException - le fichier cible n'existe pas�;
- java.io.FileNotFoundException - le fichier cible n'existe pas�;
- java.lang.InterruptedException - le thread courant a vu son sommeil �tre interrompu.
Runtime exception
Ces exceptions peuvent �tre g�n�r�es au cours de l�ex�cution (runtime) de votre code en suivant des conditions qui ne sont pas forcement pr�visibles. Il peut s'agir, par exemple, d'un param�tre non valide dans une m�thode, d'une erreur sur une op�ration math�matique, d'un d�passement d'indice de tableau ou de liste ou encore d'un d�passement de taille de tampon ou encore l'invocation d'une m�thode sur une r�f�rence qui est � la valeur null. Le compilateur ne force pas la d�claration de ces exceptions dans les signatures de m�thodes (il reste cependant possible de les d�clarer dans les signatures de m�thodes) et ne va pas v�rifier leur g�n�ration possible lors de la compilation�; vous devez donc v�rifier votre code et vos algorithmes pour �viter qu'elles ne soient g�n�r�es. Ces exceptions h�ritent toutes de la classe java.lang.RuntimeException et sont principalement � usage de la JVM�; vous ne serez donc pas amen� � en impl�menter, mais vous serez amen� � les manipuler pour traiter ce genre d'erreurs.
Quelques exemples�:
- java.lang.NullPointerException - la r�f�rence sur laquelle vous avez invoqu� une m�thode ou un membre est � la valeur null�;
- java.lang.IllegalArgumentException - le param�tre de la m�thode n'est pas valide�;
- java.lang.IndexOutOfBoundsException - l'index du tableau ou de la collection n'est pas valide�;
- java.lang.ArrayIndexOutOfBoundsException - g�n�ralement g�n�r�e par les acc�s sur des tableaux�; permet de conserver la valeur d'index non valide�;
- java.lang.ArrayIndexOutOfBoundsException - g�n�ralement g�n�r�e par les acc�s sur des tableaux�; permet de conserver la valeur d'index non valide�;
- java.lang.NumberFormatException - une erreur est survenue lors de la tentative de parser un nombre � partir d'une cha�ne de caract�res.
Error
Ces erreurs sont g�n�r�es dans le cas de situations anormales pour signaler un probl�me s�rieux qui ne devrait jamais survenir, par exemple, lorsque la JVM a consomm� toute la m�moire qui est � sa disposition et qu'elle ne peut plus en allouer, une erreur de type java.lang.OutOfMemoryError est lanc�e. Cette erreur peut survenir sur n'importe quelle instruction de votre code et il est donc pr�f�rable de ne pas essayer de la capturer, mais plut�t d'essayer de r�soudre en amont le probl�me qui a provoqu� ce lancement pour �viter qu'il ne se reproduise par la suite. Ces erreurs h�ritent de la classe java.lang.Error. Le compilateur ne force pas la d�claration de ces erreurs dans les signatures de m�thodes et ne va pas v�rifier leur lancement possible lors de la compilation.
Quelques exemples�:
- java.lang.AssertionError - le test d'une assertion a �chou�;
- java.lang.OutOfMemoryError - la JVM ne peut plus allouer de m�moire.
Pour lancer ou d�clencher une exception, il vous faut tout d'abord un objet de type java.lang.Throwable, g�n�ralement une exception de type checked ou runtime fournie par l'API Java ou la biblioth�que que vous utilisez, ou d'un type que vous avez cr�� de toute pi�ce. Lorsque l'initialisation de cette exception est finalis�e, vous pouvez la lancer gr�ce au mot-cl� throw.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 | MonException monException = new MonException("Il y a eu une erreur"); throw monException; |
Toutes les instructions situ�es apr�s le throw sont inaccessibles�; le compilateur vous g�n�rera une erreur indiquant que ces instructions ne sont pas atteignables (unreachable statement).
Si votre exception est de type runtime, vous n��tes pas forc� de la d�clarer dans la signature de la m�thode dans laquelle elle est lanc�e. Cependant, cela reste une bonne pratique que de l'y inclure et de la mentionner �galement dans la javadoc de cette m�thode.
Si votre exception est de type checked, vous devez�:
- soit la traiter dans le corps de la m�thode pour �viter qu'elle ne remonte � un niveau sup�rieur�;
- soit la d�clarer dans la signature de la m�thode pour qu'une m�thode appelante puisse la traiter.
La d�claration d'une exception dans une signature de m�thode se fait � l'aide du mot-cl� throws (avec un s � la fin) plac� en fin de signature et suivi de la liste de tous les types d'exceptions qui peuvent �tre lanc�es par la m�thode s�par�s par des virgules. Il est �galement fortement recommand� de la d�crire dans la javadoc de la m�thode via le tag @exception ou @throws.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * Ma m�thode � moi. * @param parametre1 Le param�tre de la m�thode. * @throws NullPointerException Si {@code parametre1} est {@code null}. * @throws MonException En cas d'erreur. */ public void maMethode(String parametre1) throws NullPointerException, MonException { Objects.requireNonNull(parametre1); // Peut signaler une NullPointerException [...] if (testEchoue) { // Si le test �choue, on signale une MonException. MonException monException = new MonException("Il y a eu une erreur"); throw monException; } } |
Pour capturer ou attraper une exception, vous devez utiliser un bloc try-catch ou try-catch-finally. Vous placerez votre traitement de l'exception dans le bloc catch de cette structure.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 | try { // Instructions pr�c�dentes. maMethode("toto");// M�thode pouvant signaler une MonException. // Instructions suivantes. } catch (MonException e) { // Traitement � effectuer sur l'exception. [...] } |
Ici, si une exception est signal�e dans maMethode(), toutes les instructions qui se trouvent apr�s son invocation seront ignor�es et ce jusqu'au bloc catch qui permet de capturer l'erreur. Si aucune exception n'est signal�e, les instructions qui se trouvent apr�s l'invocation de la m�thode seront ex�cut�es normalement et le contenu du bloc catch sera ignor�.
Il est tout � fait possible de r�g�n�rer une exception depuis un bloc catch apr�s avoir effectu� des traitements (fermetures de connexion, enregistrement dans un journal, etc.) de mani�re � la faire passer dans un niveau plus �lev� de l'application (ex.�: interface graphique pour afficher son message d'erreur) en invoquant le mot-cl� throw.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 | try { // Instructions pr�c�dentes. maMethode("toto");// M�thode pouvant g�n�rer une MonException. // Instructions suivantes. } catch (MonException e) { // Traitement � effectuer sur l'exception. [...] throw e; } |
Dans ce cas, les r�gles concernant la signature de la m�thode s'appliquent de mani�re identique � celles vues pr�c�demment.
Il existe plusieurs mani�res de capturer plusieurs exceptions�:
Plusieurs blocs catch
Il est possible d'encha�ner plusieurs blocs catch de mani�re � traiter toutes les exceptions susceptibles d��tre signal�es par une m�thode ou un bloc de code. Dans le cas o� vous d�sirez capturer une exception sp�cifique, vous devez traiter celle-ci avant le type plus g�n�ral.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | try { // Action signalant une exception. } catch (FileNotFoundException e1) { // Traitement sp�cifique pour l'absence de fichier. } catch (IOException e2) { // Traitement g�n�ral pour les erreurs d�entr�e/sortie. } catch (NullPointerException e3) { // Traitement pour un probl�me de r�f�rence nulle. } catch (Throwable t) { // Traitement g�n�rique pour des exceptions de type runtime non planifi�es. } |
Super type
Il est possible de r�duire le nombre de blocs catch en utilisant un type parent commun entre les exceptions. Ainsi lorsque les traitements � effectuer sont identiques, il devient plus rapide de capturer une IOException plut�t que de r�p�ter exactement le m�me bloc de traitement pour une FileNotFoundException, ZipException ou ClosedChannelException. On peut donc remplacer�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 | try { // Action signalant une exception. } catch (FileNotFoundException e1) { // Traitement. } catch (ZipException e2) { // Traitement identique au pr�c�dent. } catch (ClosedChannelException e3) { // Traitement identique au pr�c�dent. } |
Par�:
Code Java : | S�lectionner tout |
1 2 3 4 5 | try { // Action signalant une exception. } catch (IOException e) { // Traitement. } |
Note�: avant le JDK�7, le compilateur ne peut pas d�terminer le type correct de l'exception si elle est r�g�n�r�e dans le bloc catch. Une telle m�thode serait donc oblig�e de se d�clarer comme signalant le type commun utilis�: IOException. � partir du JDK�7, le compilateur est capable d�inf�rer correctement les types des exceptions g�n�r�es par les m�thodes incluses dans le bloc try, il est donc possible de sp�cifier que la m�thode peut lancer le trio FileNotFoundException, ZipException ou ClosedChannelException.
Bloc multi-catch
Depuis le JDK�8, il est possible de fusionner des blocs catch en un bloc multi-catch de mani�re � �viter la duplication de code pour les traitements. Ainsi, pr�c�demment on �crivait�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 | try { // Action signalant une exception. } catch (IOException e1) { // Traitement. } catch (SQLException e2) { // Traitement. } |
D�sormais, il est possible de fusionner toutes les exceptions dans une seule d�claration en s�parant chacun des types par une barre verticale�:
Code Java : | S�lectionner tout |
1 2 3 4 5 | try { // Action signalant une exception. } catch (IOException | SQLException ex) { // Traitement. } |
Dans le cas d'une utilisation d'un bloc finally, le contenu de ce bloc est tout le temps ex�cut� apr�s le bloc try et, s'il est pr�sent, le bloc catch m�me quand aucune exception n'est signal�e.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 | try { maMethode("toto"); // M�thode pouvant signaler une MonException. } catch (MonException e) { // Traitement � effectuer sur l'exception. [...] } finally { // Le contenu de ce bloc est tout le temps ex�cut� que l'exception soit signal�e ou pas. [...] } |
Le bloc finally permet de faire du nettoyage � la fin d'un bloc de code, par exemple fermer les flux ou les fichiers, les connexions vers des bases de donn�es, etc. tant quand le code s�ex�cute correctement que quand il �choue � cause d'une erreur. Vous devez cependant prendre garde � ce que les instructions contenues dans ce bloc ne g�n�rent pas elles-m�mes de nouvelles exceptions lorsqu'elles s�ex�cutent sous peine de ne pas pouvoir finaliser vos nettoyages.
Note�: les blocs try-finally permettent d'effectuer des traitements en cas d'exception ou d'erreur, mais ils n�emp�chent pas la remont�e de cette derni�re au niveau sup�rieur. Dans ce cas, l'exception doit �tre d�clar�e dans la signature de la m�thode appelante.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 | public void uneAutreMethode() throws MonException { try { maMethode("toto"); // M�thode pouvant signaler une MonException. } finally { // Le contenu de ce bloc est tout le temps ex�cut� que l'exception soit signal�e ou pas. [...] } } |
Depuis le JDK�7, il est possible de s'affranchir de la n�cessit� d'utiliser des blocs finally pour fermer manuellement des ressources telles que des flux ou des connexions. En effet, la syntaxe try-with-resources permet d'avoir une fermeture automatique de tout objet qui �tend l'interface java.lang.AutoCloseable.
Par exemple lors de la lecture de flux, il fallait pr�c�demment faire quelque chose du genre�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 | InputStream input = null; try { input = new FileInputStrean(fichier); // Peut signaler une IOException. [...] // Op�rations qui peuvent signaler une IOException. } finally { if (input!= null) { input.close(); // Peut signaler une IOException. } } |
Ce qui devenait vite assez compliqu� � lire lorsqu'on manipulait plusieurs flux d�entr�e/sortie.
Depuis le JDK�7, il est possible de simplifier la chose en faisant�:
Code Java : | S�lectionner tout |
1 2 3 | try (InputStream input = new FileInputStrean(fichier)) { // Peut signaler une IOException. [...] // Op�rations qui peuvent signaler une IOException. } |
Ici, si l'initialisation du flux a �t� couronn�e de succ�s, ce dernier sera automatiquement ferm� � la fin du du bloc try, m�me en cas de g�n�ration d'exception.
Il est �galement possible de d�clarer plusieurs variables dans un tel bloc�:
Code Java : | S�lectionner tout |
1 2 3 | try (InputStream input = new FileInputStrean(fichier)�; InputStreamReader reader = new InputStreamReader(input)) { // Peuvent signaler une IOException. [...] // Op�rations qui peuvent g�n�rer une IOException. } |
Ici, les deux entit�s seront automatiquement ferm�es (dans l'ordre inverse de leur d�claration) � la fin du bloc try.
Une exception peut �galement contenir une autre exception qui est sa cause directe. Cette cause est accessible via la m�thode getCause().
Par exemple, imaginons que vous soyez en train de lire le contenu d'un fichier texte�: votre code �choue � parser un entier, car les donn�es dans le fichier ne sont pas dans un format correct. Ceci g�n�re en g�n�ral une exception de type NumberFormatException. Mais pour les besoins de votre application, vous ne g�rez que des exceptions de type IOException en cas d��chec de la lecture de votre fichier. Il est possible de cr�er une nouvelle exception de type IOException et d'indiquer que l'exception de type NumberFormatException en est la cause.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | try { // Lecture du contenu du fichier. } catch (NumberFormatException e1) { IOException e2 = new IOException("Erreur de lecture du fichier", e1); throw e2; } |
Pour les types d'exception qui ne supportent pas le cha�nage de la cause dans leur constructeur, il est possible d'invoquer la m�thode initCause() pour cha�ner une exception dans une autre�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 | try { // Lecture du contenu du fichier. } catch (NumberFormatException e1) { IOException e2 = new IOException("Erreur de lecture du fichier"); e2.initCause(e1); throw e2; } |
L�analyse de la trace de cette exception d�entr�e/sortie montrera bien qu'elle a �t� g�n�r�e � cause d'une exception signal�e lors de l�interpr�tation du contenu du fichier.
� partir du JDK�7, une exception ou une erreur peut contenir plusieurs autres exceptions dites supprim�es (suppressed) et accessibles dans un tableau retourn� via la m�thode getSuppressed(). Cette mani�re de cha�ner des exceptions est utilis�e dans des domaines qui doivent �tre plus tol�rants aux fautes et erreurs d�ex�cution.
Par exemple, dans le cas d'une utilisation d'un bloc try-with-resources contenant de nombreux flux, une exception peut �tre g�n�r�e lors de la fermeture de chacun des flux. Si votre code signale une exception, la JVM va ��supprimer�� les divers signalements d'exception lors des fermetures de toutes les ressources et ce de mani�re � les g�rer correctement. � la fin du traitement, elle va toutes les empaqueter en tant qu'exceptions supprim�es dans l'exception signal�e par votre code.
Note�: le tableau retourn� par la m�thode getSuppressed() est vide lorsque l'exception ne contient pas d'exception supprim�e.
Pour ajouter une ou plusieurs exceptions supprim�es dans une exception, vous pouvez invoquer sa m�thode addSuppressed().
Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | List<Throwable> suppressed = new LinkedList<>; // Faire une ou plusieurs actions susceptibles de signaler des exceptions non critiques. // Comme ces exceptions ne sont pas critiques, elles n'interrompent pas le traitement, mais elles doivent �tre conserv�es. try { [...] } catch (UneExceptionNonCritique erreur) { suppressed.add(erreur); } // Fin du traitement. // Si des exceptions ont �t� supprim�es, on g�n�re une exception les contenant. if (!suppressed.isEmpty()) { ExceptionMajeure ex = new ExceptionMajeure("Il y a eu des erreurs durant le traitement�!"); for (Throwable t�: suppressed) { ex.addSuppressed(t); } throw ex; } |
Les articles concernant null ou les NullPointerException et comment les �viter sont nombreux. Ils pr�sentent des arguments int�ressants, mais manquent souvent les aspects faciles, s�rs et �l�gants de la classe java.util.Optional propos�e depuis le JDK�8.
En partant de ce code :
Code Java : | S�lectionner tout |
1 2 | String unsafeTypeDirName = project.getApplicationType().getTypeDirName(); System.out.println(unsafeTypeDirName); |
Avant le JDK 8
Il est �vident que si une des valeurs utilis�es ou retourn�es dans la premi�re ligne est null, une exception de type NullPointerException sera signal�e.
Voici une mani�re typique de r�soudre ce probl�me :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 | // S�r, mais pas tr�s �l�gant, et un oubli est vite arriv� if (project != null) { ApplicationType applicationType = project.getApplicationType(); if (applicationType != null) { String typeDirName = applicationType.getTypeDirName(); if (typeDirName != null) { System.out.println(typeDirName); } } } |
Si ce code r�sout bien le probl�me, il n�est pas tr�s joli.
JDK 8
Essayons avec la classe Optional de Java�8.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // Supposons que c�est ce que le mod�le retournera dans le futur ; en attendant... Optional<Project> optionalProject = Optional.ofNullable(project); // S�r, mais toujours peu s�duisant et sujet � omissions. if (optionalProject.isPresent()) { ApplicationType applicationType = optionalProject.get().getApplicationType(); Optional<ApplicationType> optionalApplicationType = Optional.ofNullable(applicationType); if (optionalApplicationType.isPresent()) { String typeDirName = optionalApplicationType.get().getTypeDirName(); Optional<String> optionalTypeDirName = Optional.ofNullable(typeDirName); if (optionalTypeDirName.isPresent()) { System.out.println(optionalTypeDirName); } } } |
Comme observ� par plusieurs, cette version n�est pas r�ellement diff�rente des comparaisons � null. Certains y voient une clarification de l�intention. Je n�y vois pas de gain significatif, l�exemple pr�c�dent montrant que l�intention est d�j� assez claire pour une situation de ce type.
Essayons donc avec une approche plus fonctionnelle, qui permet d�utiliser plus de puissance de la classe Optional.
Code Java : | S�lectionner tout |
1 2 3 4 5 | // S�r, plus �l�gant. optionalProject .map(project -> project.getApplicationType()) .map(applicationType -> applicationType.getTypeDirName()) .ifPresent(typeDirName -> System.out.println(typeDirName)); |
map() retournera toujours une instance de Optional, les null �tant d�s lors impossibles. Il n�est d�s lors plus n�cessaire de convertir les valeurs de et vers Optional.
ifPresent() ex�cutera le code seulement si une valeur est sp�cifi�e. Pas besoin d�une valeur par d�faut.
Pour exprimer la m�me chose plus succinctement, passons � des r�f�rences de m�thodes :
Code Java : | S�lectionner tout |
1 2 3 4 5 | // S�r, plus gracieux. optionalProject .map(Project::getApplicationType) .map(ApplicationType::getTypeDirName) .ifPresent(System.out::println); |
En utilisant Optional et en ne travaillant jamais avec null, il est possible d��viter compl�tement les NullPointerException. Comme cet artifice n�est plus utilis�, on �vite d�oublier une comparaison � null, source d�erreurs. Bien entendu, il faut pour cela traiter au plus vite les valeurs retourn�es par du code ancien pouvant retourner null (List, Set, Map�). Les convertir au plus vite en Optional permettra d��viter tout souci.
Proposer une nouvelle r�ponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �aLes sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.