La semaine dernière, nous avons eu un débat passionné sur la gestion des valeurs NULL dans la couche de service de notre application. La question se situe dans le contexte .NET, mais ce sera la même chose en Java et dans de nombreuses autres technologies.
La question était: devriez-vous toujours vérifier les nulls et faire fonctionner votre code à tout moment, ou laisser une exception bouillonner quand une null est reçue de manière inattendue?
D'un côté, vérifier la valeur null là où vous ne l'attendez pas (c'est-à-dire ne pas avoir d'interface utilisateur pour la gérer) est, à mon avis, identique à l'écriture d'un bloc try avec un catch vide. Vous ne faites que cacher une erreur. L'erreur peut être que quelque chose a changé dans le code et que null est maintenant une valeur attendue, ou il y a une autre erreur et un ID incorrect est transmis à la méthode.
En revanche, vérifier les valeurs nulles peut être une bonne habitude en général. De plus, s’il ya vérification, l’application peut continuer à fonctionner, seule une petite partie de la fonctionnalité n’ayant aucun effet. Ensuite, le client peut signaler un petit bogue du type "impossible de supprimer un commentaire" au lieu d'un bogue beaucoup plus grave tel que "impossible d'ouvrir la page X".
Quelle pratique suivez-vous et quels sont vos arguments pour ou contre l'une ou l'autre approche?
Mise à jour:
Je veux ajouter quelques détails sur notre cas particulier. Nous avons récupéré des objets de la base de données et les avons traités (construisons une collection, par exemple). Le développeur qui a écrit le code n'a pas prévu que l'objet puisse être null et n'a donc inclus aucune vérification. Lors du chargement de la page, une erreur s'est produite et la totalité de la page n'a pas été chargée.
Évidemment, dans ce cas, il aurait dû y avoir un contrôle. Nous nous sommes ensuite demandé si tous les objets traités devaient être vérifiés, même s'ils ne devaient pas être manquants, et si le traitement éventuel devait être interrompu en mode silencieux.
L'avantage hypothétique serait que la page continuera à fonctionner. Pensez à des résultats de recherche sur Stack Exchange dans différents groupes (utilisateurs, commentaires, questions). La méthode pourrait vérifier la valeur null et abandonner le traitement des utilisateurs (ce qui, en raison d'un bogue, a la valeur null), mais renvoyer les sections "comments" et "questions". La page continuerait à fonctionner sauf que la section "utilisateurs" serait manquante (ce qui est un bogue). Devrions-nous échouer tôt et casser toute la page ou continuer à travailler et attendre que quelqu'un remarque la section "utilisateurs" manquante?
la source
assert(foo != null, "foo is web control within the repeater, there's no reason to expect it to be null, etc, etc...");
Réponses:
La question n'est pas tant de savoir si vous devez vérifier
null
si le moteur d'exécution génère une exception. c'est comment vous devriez réagir à une situation aussi inattendue.Vos options sont alors:
NullReferenceException
) et laissez-la bouillonner; Si vous ne faites pas lenull
contrôle vous-même, c'est ce qui se produit automatiquement.null
chèque, soit en attrapant unNullReferenceException
et en lançant l'exception plus spécifique.Il n'y a pas de règle générale pour déterminer laquelle est la meilleure solution. Personnellement, je dirais:
la source
IMHO essayer de gérer des valeurs NULL que vous n'attendez pas conduit à un code trop compliqué. Si vous ne vous attendez pas à null, clarifiez-le en jetant
ArgumentNullException
. Je suis vraiment frustré lorsque les gens vérifient si la valeur est nulle et essaient ensuite d'écrire du code qui n'a aucun sens. Il en va de même pour l'utilisationSingleOrDefault
(ou pire encore pour la collecte) lorsque quelqu'un s'attend vraiment,Single
et de nombreux autres cas où les gens ont peur (je ne sais pas vraiment de quoi) énoncer clairement leur logique.la source
ArgumentNullException
, vous devriez utiliser des contrats de code (sauf s'il s'agit d'un code source antérieur à 2010 qui ne prend pas en charge les contrats de code).ArgumentNullException
compte comme "manipulant" la valeur NULL: cela empêche une exception de référence Null ultérieure.ArgumentNullException
explique très clairement quel est le problème et comment le résoudre. C # n'a pas tendance à utiliser "indéfini". Si vous appelez quelque chose d'une manière qui n'est pas définie, la façon dont vous l'appelez n'a pas de sens. Une exception est la bonne façon de l'indiquer. Maintenant, parfois, je crée des méthodes d'analyse qui renvoient null si leint
(par exemple) ne peut pas être analysé. Mais c'est un cas où un résultat imparable est une possibilité légitime plutôt qu'une erreur d'utilisation. Voir aussi cet article .L'habitude de vérifier pour
null
mon expérience vient des anciens C ou C ++ développeurs, dans les langues que vous avez une bonne chance de cacher une erreur grave lors de ne pas vérifier pourNULL
. Comme vous le savez, en Java ou en C #, les choses sont différentes, utiliser une référence null sans recherchernull
une exception provoquera une exception. Ainsi, l'erreur ne sera pas cachée secrètement tant que vous ne l'ignorerez pas du côté de l'appelant. Ainsi, dans la plupart des cas, la recherche explicite denull
n'a pas beaucoup de sens et complique le code plus que nécessaire. C'est pourquoi je ne considère pas la vérification nulle comme une bonne habitude dans ces langues (du moins, pas en général).Bien sûr, il y a des exceptions à cette règle, voici celles auxquelles je peux penser:
vous voulez un meilleur message d'erreur, lisible par l'homme, indiquant à l'utilisateur dans quelle partie du programme la mauvaise référence null s'est produite. Votre test pour null génère donc une exception différente, avec un texte d'erreur différent. De toute évidence, aucune erreur ne sera masquée de cette façon.
vous voulez que votre programme "échoue plus tôt". Par exemple, vous souhaitez vérifier la valeur null d'un paramètre de constructeur, où la référence de l'objet ne serait sinon stockée que dans une variable membre et utilisée ultérieurement.
vous pouvez gérer la situation d'une référence nulle en toute sécurité, sans risque de défaillance ultérieure et sans masquer une erreur grave.
vous voulez un type de signalisation d'erreur complètement différent (par exemple, renvoyer un code d'erreur) dans votre contexte actuel
la source
Utilisez des assertions pour tester et indiquer les pré / post-conditions et les invariants de votre code.
Il est tellement plus facile de comprendre ce que le code attend et ce que l’on peut s’attendre à gérer.
Une affirmation, IMO, est un chèque approprié car il s’agit de:
Je pense que le code auto-documenté est important, donc avoir une vérification est bien. La programmation défensive, rapide après échec, facilite beaucoup la maintenance, où l’on passe généralement le plus de temps possible.
Mise à jour
Wrt votre élaboration. Il est généralement utile de donner à l'utilisateur final une application qui fonctionne bien sous les bogues, c'est-à-dire autant que possible. La robustesse est bonne, car le ciel ne sait que ce qui se brisera à un moment critique.
Cependant, les développeurs et les testeurs doivent être conscients des bogues dès que possible, vous souhaiterez donc probablement une infrastructure de journalisation avec un point d'ancrage pouvant afficher une alerte à l'utilisateur en cas de problème. L'alerte devrait probablement être affichée pour tous les utilisateurs, mais peut probablement être adaptée différemment en fonction de l'environnement d'exécution.
la source
Échouer tôt, échouer souvent.
null
est l’une des meilleures valeurs inattendues que vous puissiez obtenir, car vous pouvez rapidement échouer dès que vous essayez de l’utiliser. D'autres valeurs inattendues ne sont pas si faciles à détecter. Comme celanull
échoue automatiquement pour vous chaque fois que vous essayez de l’utiliser, je dirais que cela ne nécessite pas de vérification explicite.la source
Rechercher une valeur nulle devrait être votre seconde nature
Votre API sera utilisée par d'autres personnes et leurs attentes seront probablement différentes des vôtres.
Les tests unitaires approfondis mettent normalement en évidence la nécessité d'une vérification de la référence nulle
La vérification des valeurs NULL n'implique pas d'instructions conditionnelles. Si vous craignez que la vérification null rend votre code moins lisible, vous pouvez envisager des contrats de code .NET.
Pensez à installer ReSharper (ou similaire) pour rechercher dans votre code les vérifications de références nulles manquantes.
la source
Je considérerais la question du point de vue de la sémantique, c'est-à-dire me demander ce que représente un pointeur NULL ou un argument de référence nul.
Si une fonction ou une méthode foo () a un argument x de type T, x peut être obligatoire ou facultatif .
En C ++, vous pouvez passer un argument obligatoire en tant que
Dans les deux cas, vous n'avez pas le problème de vérifier un pointeur NULL. Ainsi, dans de nombreux cas, vous n'avez pas besoin d' une vérification de pointeur NULL à tous pour les arguments obligatoires.
Si vous transmettez un argument facultatif , vous pouvez utiliser un pointeur et utiliser la valeur NULL pour indiquer qu'aucune valeur n'a été fournie:
Une alternative consiste à utiliser un pointeur intelligent comme
Dans ce cas, vous voudrez probablement vérifier le pointeur dans le code, car la méthode foo () fait la différence si x contient une valeur ou aucune valeur.
Le troisième et dernier cas est que vous utilisez un pointeur pour un argument obligatoire . Dans ce cas, appeler foo (x) avec x == NULL est une erreur et vous devez décider comment le gérer (de la même manière qu'avec un index hors limite ou toute entrée non valide):
Mis à part une façon plus agréable d’échouer (en donnant à l’utilisateur plus d’informations), la deuxième approche présente un avantage: il est plus probable que le bogue soit trouvé: le programme échouera chaque fois que la méthode est appelée avec les arguments incorrects approche 1, le bogue n'apparaît que si une instruction de déréférencement du pointeur est exécutée (par exemple, si la branche droite d'une instruction if est entrée). Donc, l'approche 2 offre une forme plus forte d '"échec précoce".
En Java, vous avez moins de choix, car tous les objets sont transmis à l'aide de références qui peuvent toujours être nulles. De nouveau, si la valeur null représente la valeur NONE d'un argument facultatif, la vérification de cette valeur fera (probablement) partie de la logique d'implémentation.
Si la valeur null est une entrée non valide, vous avez une erreur et j'appliquerais les mêmes considérations que pour le cas des pointeurs C ++. Comme en Java vous pouvez intercepter des exceptions de pointeur nul, l'approche 1 ci-dessus est équivalente à l'approche 2 si la méthode foo () déréférence tous les arguments d'entrée dans tous les chemins d'exécution (ce qui se produit probablement très souvent pour les petites méthodes).
Résumant
MODIFIER
Merci à Stilgar pour plus de détails.
Dans votre cas, il semble que vous ayez null comme résultat d'une méthode. Encore une fois, je pense que vous devriez d’abord clarifier (et corriger) la sémantique de vos méthodes avant de pouvoir prendre une décision.
Donc, vous avez la méthode m1 () appelant la méthode m2 () et m2 () renvoie une référence (en Java) ou un pointeur (en C ++) à un objet.
Quelle est la sémantique de m2 ()? M2 () doit-il toujours renvoyer un résultat non nul? Si tel est le cas, un résultat NULL est une erreur interne (en m2 ()). Si vous vérifiez la valeur de retour dans m1 (), la gestion des erreurs peut être plus robuste. Si vous ne le faites pas, vous aurez probablement une exception, tôt ou tard. Peut être pas. J'espère que l'exception est levée pendant les tests et non après le déploiement. Question : si m2 () ne doit jamais renvoyer null, pourquoi renvoie-t-il null? Peut-être devrait-il lancer une exception à la place? m2 () est probablement buggy.
L’alternative est que le retour de null fait partie de la sémantique de la méthode m2 (), c’est-à-dire qu’il a un résultat optionnel, qui devrait être documenté dans la documentation Javadoc de la méthode. Dans ce cas, il est correct d'avoir une valeur nulle. La méthode m1 () devrait la vérifier comme toute autre valeur: il n'y a pas d'erreur ici, mais la vérification probable que le résultat est null fait simplement partie de la logique du programme.
la source
Mon approche générale est de ne jamais rechercher une condition d'erreur que vous ne savez pas comment gérer . La question à laquelle il faut répondre dans chaque cas particulier devient alors: pouvez-vous faire quelque chose de raisonnable en présence de la
null
valeur inattendue ?Si vous pouvez continuer en toute sécurité en substituant une autre valeur (une collection vide, par exemple, ou une valeur ou instance par défaut), alors ne vous gênez pas. @ L'exemple de Shahbaz, tiré de World of Warcraft, consistant à remplacer une image par une autre tombe dans cette catégorie; l'image elle-même n'est probablement qu'une décoration et n'a aucun impact fonctionnel . (Dans une version de débogage, j'utiliserais une couleur criarde pour attirer l'attention sur le fait qu'une substitution s'est produite, mais cela dépend grandement de la nature de l'application.) Consignez les détails de l'erreur, cependant, afin que vous sachiez qu'elle se produit; sinon, vous cachez une erreur que vous souhaitez probablement connaître. Le cacher à l'utilisateur est une chose (encore une fois, en supposant que le traitement puisse continuer en toute sécurité); le cacher au développeur en est une autre.
Si vous ne pouvez pas continuer en toute sécurité en présence d'une valeur NULL, échouez avec une erreur sensible; en général, je préfère échouer dès que possible lorsqu'il est évident que l'opération ne peut pas aboutir, ce qui implique de vérifier les conditions préalables. Il y a des moments où vous ne voulez pas échouer immédiatement, mais différer l'échec le plus longtemps possible; cette considération se pose par exemple dans les applications liées à la cryptographie, où les attaques par canal latéral pourraient sinon divulguer des informations que vous ne voulez pas connaître. À la fin, laissez l’erreur remonter jusqu’à un gestionnaire d’erreurs général, qui enregistre à son tour les détails pertinents et affiche un beau message d’erreur (même s'il peut être gentil) à l’utilisateur.
Il convient également de noter que la réponse appropriée peut très bien différer entre les versions test / QA / débogage et les versions production / édition. Dans les versions de débogage, j'accepterais l'échec précoce et difficile avec des messages d'erreur très détaillés, afin de rendre tout à fait évident qu'il y a un problème et de permettre à un post-mortem de déterminer ce qu'il faut faire pour le résoudre. Les versions de production, confrontées à des erreurs récupérables en toute sécurité , devraient probablement favoriser la récupération.
la source
Bien sûr, ce
NULL
n'est pas prévu , mais il y a toujours des bugs!Je crois que vous devriez vérifier
NULL
si vous ne vous y attendez pas ou non. Laissez-moi vous donner des exemples (bien qu'ils ne soient pas en Java).Dans World of Warcraft, en raison d'un bug, l'image de l'un des développeurs apparaissait sur un cube pour de nombreux objets. Imaginez si le moteur graphique ne s'attendait pas à des
NULL
pointeurs, il y aurait eu un crash, alors que cela deviendrait une expérience peu fatale (même drôle) pour l'utilisateur. Le moins est que vous n’auriez pas perdu de façon inattendue votre connexion ou l’un de vos points de sauvegarde.Voici un exemple où la vérification de la valeur NULL a empêché un blocage et le traitement silencieux de l’affaire.
Imaginez un programme de caissier de banque. L'interface effectue certaines vérifications et envoie les données d'entrée à une partie sous-jacente pour effectuer les transferts d'argent. Si la partie principale s'attend à ne pas recevoir
NULL
, alors un bogue dans l'interface peut causer un problème dans la transaction, éventuellement de l'argent perdu au milieu (ou pire, dupliqué).Par "un problème", j'entends un crash (comme dans un crash (disons que le programme est écrit en C ++), pas une exception de pointeur nul). Dans ce cas, la transaction doit être annulée si NULL est rencontré (ce qui ne serait bien entendu pas possible si vous ne compariez pas les variables à NULL!)
Je suis sûr que vous avez l'idée.
Contrôler la validité des arguments de vos fonctions n’encombre pas votre code, c’est deux vérifications au sommet de votre fonction (non réparties au milieu) et il augmente considérablement la robustesse.
Si vous devez choisir entre "le programme indique à l'utilisateur qu'il a échoué et qu'il s'arrête ou revient à un état cohérent, créant éventuellement un journal des erreurs" et "Violation d'accès", ne choisissez-vous pas le premier? Cela signifie que chaque fonction doit être préparée pour être appelée par un code de bug plutôt que de s'attendre à ce que tout soit correct, tout simplement parce que les bogues existent toujours.
la source
Comme indiqué dans les autres réponses Si vous ne vous attendez pas
NULL
, précisez-le en jetantArgumentNullException
. À mon avis, lorsque vous déboguez le projet, cela vous aide à découvrir plus tôt les erreurs dans la logique de votre programme.Donc, vous allez libérer votre logiciel, si vous restaurez ces
NullRefrences
vérifications, vous ne manquerez rien de la logique de votre logiciel, cela fera double-ment la certitude qu'un bug grave ne surviendra pas.Un autre point est que si la
NULL
vérification concerne les paramètres d'une fonction, vous pouvez alors décider si la fonction est le bon endroit pour le faire ou non. sinon, trouve toutes les références à la fonction, puis avant de passer un paramètre à la fonction, examinez les scénarios probables pouvant conduire à une référence nulle.la source
Chaque
null
système de votre système est une bombe à retardement à découvrir. Rechercheznull
les limites où votre code interagit avec du code que vous ne contrôlez pas et interdisez-lenull
dans votre propre code. Cela vous évite le problème sans faire naïvement confiance à un code étranger. Utilisez des exceptions ou une sorte deMaybe
/Nothing
type à la place.la source
Bien qu'une exception de pointeur nul soit éventuellement levée, elle le sera souvent loin du point où vous avez obtenu le pointeur nul. Faites-vous une faveur et raccourcissez le temps nécessaire à la résolution du bogue en enregistrant au moins le fait que vous générez un pointeur nul dès que possible.
Même si vous ne savez pas quoi faire maintenant, la journalisation de l'événement vous fera gagner du temps. Et peut-être que le gars qui recevra le billet pourra utiliser le temps gagné pour trouver la bonne réponse.
la source
Comme
Fail early, fail fast
indiqué par @DeadMG (@empi) n'est pas possible, car l'application Web doit bien fonctionner sous les bogues, vous devez appliquer la règle.pas d'exception attraper sans se connecter
en tant que développeurs, vous êtes donc au courant des problèmes potentiels en inspectant les journaux.
Si vous utilisez une structure de journalisation telle que log4net ou log4j, vous pouvez configurer une sortie de journalisation spéciale supplémentaire (appelée appender)
qui vous enverra des erreurs et des erreurs fatales. afin que vous restiez informé.[mise à jour]
si l'utilisateur final de la page ne doit pas être conscient de l'erreur, vous pouvez configurer un éditeur qui vous enverra des erreurs et des erreurs fatales qui vous informeront.
s'il est correct que l'utilisateur final de la page voie des messages d'erreur cryptiques, vous pouvez configurer un générateur d'appels qui place le journal des erreurs du traitement de la page à la fin de la page.
Peu importe la manière dont vous utilisez la journalisation si vous avalez l'exception, le programme continue avec des données qui ont du sens et la déglutition n'est plus silencieuse.
la source
Il y a déjà de bonnes réponses à cette question, peut-être y at-il un ajout: je préfère les assertions dans mon code. Si votre code ne peut fonctionner qu'avec des objets valides, mais non avec null, vous devez affirmer la valeur null.
Les assertions dans ce genre de situation laisseraient n'importe quel test unitaire et / ou d'intégration échouer avec le message exact. Vous pourrez ainsi résoudre le problème assez rapidement avant la production. Si une telle erreur se glisse entre les tests et passe en production (où les assertions doivent être désactivées), vous recevrez un NpEx, et un bogue grave, mais il vaut mieux qu'un bogue mineur qui est beaucoup plus flou et apparaît quelque part dans le fichier. code, et serait plus coûteux à réparer.
De plus, si quelqu'un doit travailler avec vos assertions de code l'informe de vos hypothèses de conception / écriture de votre code (dans ce cas: Hey mec, cet objet doit être présenté!), Ce qui facilite sa maintenance.
la source
Je vérifie normalement les valeurs NULL, mais je «gère» les valeurs NULL inattendues en lançant une exception qui donne un peu plus de détails sur l'emplacement exact de la valeur NULL.
Edit: Si vous obtenez une valeur nulle alors que vous ne vous attendez pas à quelque chose, le programme devrait disparaître.
la source
Cela dépend de la mise en œuvre linguistique des exceptions. Les exceptions vous permettent de prendre des mesures pour éviter d'endommager les données ou pour libérer des ressources proprement dans l'éventualité où votre système entrerait dans un état ou une condition imprévu. Cela diffère de la gestion des erreurs qui sont des conditions que vous pouvez anticiper. Ma philosophie est que vous devriez avoir le moins possible de gestion des exceptions. C'est du bruit. Votre méthode peut-elle faire quelque chose de raisonnable en gérant l'exception? Peut-il récupérer? Peut-il réparer ou prévenir d'autres dommages? Si vous attrapez simplement l'exception et revenez à la méthode ou si vous échouez d'une autre manière inoffensive, il était alors inutile de capturer l'exception. Vous n'auriez ajouté que du bruit et de la complexité à votre méthode, et vous pourriez cacher la source d'une faille dans votre conception. Dans ce cas, je laisserais la faute bouillonner et être attrapée par une boucle externe. Si vous pouvez faire quelque chose comme réparer un objet ou le marquer comme corrompu ou libérer une ressource critique telle qu'un fichier de verrouillage ou en fermant proprement un socket, il s'agit d'un bon usage des exceptions. Si vous vous attendez à ce que la valeur NULL apparaisse fréquemment comme un cas d'extrémité valide, vous devez le gérer dans le flux logique normal avec des instructions if-the-else ou switch-case ou quoi que ce soit, mais pas avec un traitement d'exception. Par exemple, un champ désactivé dans un formulaire peut être défini sur NULL, ce qui est différent d'une chaîne vide représentant un champ laissé vide. C'est un domaine dans lequel vous devez faire preuve de jugement et de bon sens. Je n'ai jamais entendu parler de bonnes règles empiriques concernant la manière de traiter ce problème dans toutes les situations. Si vous pouvez faire quelque chose comme réparer un objet ou le marquer comme corrompu ou libérer une ressource critique telle qu'un fichier de verrouillage ou en fermant proprement un socket, il s'agit d'un bon usage des exceptions. Si vous vous attendez à ce que la valeur NULL apparaisse fréquemment comme un cas d'extrémité valide, vous devez le gérer dans le flux logique normal avec des instructions if-the-else ou switch-case ou quoi que ce soit, mais pas avec un traitement d'exception. Par exemple, un champ désactivé dans un formulaire peut être défini sur NULL, ce qui est différent d'une chaîne vide représentant un champ laissé vide. C'est un domaine dans lequel vous devez faire preuve de jugement et de bon sens. Je n'ai jamais entendu parler de bonnes règles empiriques concernant la manière de traiter ce problème dans toutes les situations. Si vous pouvez faire quelque chose comme réparer un objet ou le marquer comme corrompu ou libérer une ressource critique telle qu'un fichier de verrouillage ou en fermant proprement un socket, il s'agit d'un bon usage des exceptions. Si vous vous attendez à ce que la valeur NULL apparaisse fréquemment comme un cas d'extrémité valide, vous devez le gérer dans le flux logique normal avec des instructions if-the-else ou switch-case ou quoi que ce soit, mais pas avec un traitement d'exception. Par exemple, un champ désactivé dans un formulaire peut être défini sur NULL, ce qui est différent d'une chaîne vide représentant un champ laissé vide. C'est un domaine dans lequel vous devez faire preuve de jugement et de bon sens. Je n'ai jamais entendu parler de bonnes règles empiriques concernant la manière de traiter ce problème dans toutes les situations.
Java échoue dans sa mise en œuvre de gestion des exceptions avec des "exceptions vérifiées", dans lesquelles toute exception pouvant être déclenchée par des objets utilisés dans une méthode doit être interceptée ou déclarée dans la clause "throws" de la méthode. Le est l'opposé de C ++ et de Python, où vous pouvez choisir de gérer les exceptions comme bon vous semble. En Java, si vous modifiez le corps d'une méthode pour inclure un appel susceptible de déclencher une exception, vous devez choisir d'ajouter une gestion explicite à une exception qui ne vous intéresse pas, ce qui ajoute du bruit et de la complexité à votre code. Ajoutez cette exception à la clause "Throws" de la méthode que vous modifiez, ce qui non seulement ajoute du bruit et de l'encombrement, mais modifie également la signature de votre méthode. Vous devez ensuite utiliser un code de modification chaque fois que votre méthode est utilisée pour gérer la nouvelle exception que votre méthode peut maintenant générer ou ajouter une exception à la clause "Throws" de ces méthodes, ce qui déclenche un effet de domino des modifications de code. La "Catch or Specify Requirement" est l'un des aspects les plus gênants de Java. L'exception exception pour RuntimeExceptions et la rationalisation Java officielle pour cette erreur de conception est boiteuse.
Ce dernier paragraphe avait peu à voir avec la réponse à votre question. Je déteste juste Java.
- Noé
la source