IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
logo

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.

SommaireBases du langageExceptions (10)
pr�c�dent sommaire suivant
 

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.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.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.

Mis � jour le 7 juillet 2015 bouye

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; 
    } 
}

Mis � jour le 14 avril 2015 bouye Mickael Baron

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.

Mis � jour le 14 avril 2015 bouye Mickael Baron

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. 
}

Mis � jour le 14 avril 2015 bouye Mickael Baron

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. 
        [...] 
    } 
}

Mis � jour le 14 avril 2015 bouye Mickael Baron

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.

Mis � jour le 14 avril 2015 bouye Mickael Baron

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.

Mis � jour le 8 juillet 2015 bouye

� 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.

Mis � jour le 8 juillet 2015 bouye

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; 
}

Mis � jour le 15 septembre 2015 bouye

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.

Mis � jour le 7 octobre 2015 ymajoros

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 �a


R�ponse � la question

Liens sous la question
pr�c�dent sommaire suivant
 

Les 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.