46 votes

Est-il acceptable de jeter NullPointerException par programmation?

Quand il y a une post-condition, que la valeur de retour d'une méthode ne doit pas être nulle, ce qui peut être fait ?

Je pourrais le faire

assert returnValue != null : "Not acceptable null value";

mais affirmations peut être éteint !

Alors, est-il normal de le faire

if(returnValue==null)
      {
           throw new NullPointerException("return value is null at method AAA");
      }

?

Ou est-il préférable d'utiliser un utilisateur défini par l'exception (comme NullReturnValueException ) pour qu'une telle condition ?

63voto

Roman Points 21807

Je vous recommande de ne jamais jeter NullPointerException par vous-même.

La principale raison de ne pas le faire, Thorbjørn Ravn Andersen dit dans un commentaire ci-dessous, c'est que vous n'avez pas wan pas mélanger "réelle, la mauvaise Npe" avec Npe jeté intentionnellement.

Donc, jusqu'à ce que vous êtes sûr que vous êtes capable de reconnaître les "valides" NPE, je vous recommande d'utiliser IllegalArgumentException quand vous voulez dire à votre API utilisateur null n'est pas un argument valide de valeur. Votre comportement de la méthode lorsque illégale null en paramètre passé doivent être documentés.

L'autre (plus moderne à mon humble avis) l'option est d'utiliser @NotNull d'annotation près de l'argument. Voici un article sur l'utilisation de @NotNull annotation.

Comme je l'ai mentionné plus tôt, il peut aussi y avoir des cas, lors du lancer de NPE ne sera pas source de confusion, soit à vous ou à vos coéquipiers: NPE la cause doit être clair et reconnaissable.

Par exemple, si vous utilisez une bibliothèque avec des conditions préalables module, comme Guava, puis-je trouver de l'aide checkNotNull()-comme des méthodes est une meilleure façon de traiter avec illégalement transmis les valeurs null.

checkNotNull(arg, msg) jette NPE, mais à partir de la stacktrace c'est assez claire, qu'elle a été produite par Preconditions.checkNotNull() et donc il n'est pas un bug inconnu, mais plutôt le comportement attendu.

42voto

waxwing Points 10190

Je ne vois aucun problème à jeter des entrées en phase nationale le plus tôt possible avant la JVM fait pour vous - en particulier pour les arguments null. Il semble y avoir débat sur ce sujet, mais il existe de nombreux exemples dans le Java SE bibliothèques qui fait exactement cela. Je ne vois pas pourquoi NPE doivent être saints dans l'aspect que vous n'êtes pas en mesure de jeter vous-même.

Cependant, je m'égare. Cette question est à propos de quelque chose de différent. Vous parlez d'une post-condition indiquant que la valeur de retour ne doit pas être null. Sûrement null dans ce cas serait de dire que vous avez un bug à l'intérieur de la méthode?

Comment voulez-vous même ce document? "Cette méthode lève une exception NullPointerException si la valeur de retour de façon inattendue est nul"? Sans expliquer comment cela a pu se produire? Non, je voudrais utiliser une assertion ici. Les Exceptions doivent être utilisés pour les erreurs qui peuvent éventuellement se produire - ne pas couvrir des choses qui peuvent se produire si il ya quelque chose de mal à l'intérieur de la méthode, parce que cela n'aide pas n'importe qui.

28voto

Timo Geusch Points 16952

Étant donné qu' NullPointerException est le idiomatiques façon de communiquer à une valeur null inattendue en Java, je vous recommande de jeter un standard NullPointerException et pas une maison une. Aussi garder à l'esprit que le principe de moindre surprise vous suggérons de ne pas inventer votre propre type d'exception pour les cas où un système de type d'exception existe.

Les Assertions sont bonnes pour le débogage, mais pas bon si vous avez à gérer certaines conditions, de sorte que n'est pas vraiment une bonne façon de gérer la condition d'erreur.

12voto

Lukasz Points 9471

Le problème avec NullPointerException , c'est qu'elle se passe lorsque vous oubliez de vérifier si quelque chose est nul ou donner le mauvais argument est null, et de ne pas le faire.

De mon expérience, les programmeurs Java apprendre très vite que cette exception est causée par le bug dans le code, afin de les lancer manuellement sera extremally déroutant pour la plupart d'entre eux. IllegalArgumentException est meilleure idée lorsque vous passez inacceptable argument (comme null, où quelque chose ne doit pas être null).

Il déclenche également une autre heuristique. NPE = quelqu'un a fait une erreur dans le code ici, IllegalArgumentException = l'objet donné à la méthode n'est pas valide.

D'autre part, la javadoc dit:

Les demandes doivent jeter les instances de cette classe pour indiquer
d'autres illégale de l' null objet.

Afin de lancer des NPE serait légal, cependant elle n'est pas la pratique courante, alors je vous recommandons IllegalArgumentException.

7voto

Affe Points 24993

Il n'est certainement pas une loi universelle contre jetant NullPointerException, mais il est difficile de répondre si vous avez réellement doit dans une abstraction exemple. Ce que vous ne voulez pas faire est de mettre les gens en haut de la chaîne dans la position d'essayer d'attraper NullPointerException. Code comme ceci (exemple réel, je le jure):

catch (NullPointerException npe) {
  if (npe.getMessage().equals("Null return value from getProdByCode") {
    drawToUser("Unable to find a product for the product type code you entered");
  } 
}

Est un indicateur infaillible vous êtes en train de faire quelque chose de mal. Donc, si la valeur de retour null est un indicateur de certains de l'état du système que vous êtes réellement en mesure de communiquer, d'utiliser une exception qui communique cet état. Il n'y a pas beaucoup de cas, je pense, où il fait sens, null vérifier juste une référence à chuck un nullpointer. Habituellement, la très prochaine ligne de code aurait chucked la nullpointer (ou quelque chose de plus instructif) de toute façon!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X