J'ai une simple méthode de définition d'une propriété et d' null
n'est pas approprié pour cette propriété particulière. J'ai toujours été déchiré dans cette situation: dois-je lancer un IllegalArgumentException
, ou un NullPointerException
? À partir de la documentation javadoc, les deux semblent appropriées. Est-il une sorte de une compris la norme? Ou est-ce juste une de ces choses que vous devez faire ce que vous préférez et les deux sont vraiment correcte?
Réponses
Trop de publicités?Vous devriez être en utilisant IllegalArgumentException
(IAE), pas NullPointerException
(NPE) pour les raisons suivantes:
Tout d'abord, les NPE JavaDoc explicitement énumère les cas où les NPE est approprié. Notez que tous d'entre eux sont jetés par le moteur d'exécution lors de l' null
est utilisé de façon inappropriée. En revanche, l' IAE JavaDoc ne pouvait pas être plus clair: "Levée pour indiquer qu'une méthode a été adoptée illégale ou inappropriée de l'argument." Yup, c'est vous!
Deuxièmement, lorsque vous voyez un NPE dans une trace de la pile, ce que supposez-vous? Probablement que quelqu'un déréférencé une valeur null. Quand vous voyez des IAE, vous assumez l'appelant de la méthode en haut de la pile passé dans une valeur illégale. Encore une fois, la dernière hypothèse est vraie, la première est trompeuse.
En troisième lieu, l'IAE est clairement conçu pour la validation des paramètres, vous devez l'assumer, comme le choix par défaut de l'exception, alors pourquoi voudriez-vous choisir des NPE à la place? Certainement pas pour les différents comportement -- attendez-vous d'appeler le code d'attraper des NPE est séparément de l'IAE et de faire quelque chose de différent? Êtes-vous essayer de communiquer un message d'erreur plus spécifique? Mais vous pouvez le faire à l'exception de message texte de toute façon, comme vous devriez le faire pour tous les autres des paramètres incorrects.
Quatrièmement, tous les autres paramètres incorrect de données sera de l'IAE, alors pourquoi ne pas cohérent? Pourquoi est-ce qu'un illégales null
est tellement spécial qu'il mérite une autre exception de tous les autres types d'illégal arguments?
Enfin, j'accepte l'argument donné par d'autres réponses que des parties de l'API Java utilisation des NPE dans cette manière. Toutefois, l'API Java est incompatible avec tout, des types exception des conventions de nommage, donc je pense tout simplement copier aveuglément (votre partie préférée) de l'API Java n'est pas un assez bon argument pour l'emporter sur ces autres considérations.
La norme est de jeter le NullPointerException. Généralement infaillible "Effective Java" explique brièvement dans l'Article 42 (dans la première édition) et à l'Article 60 (dans la deuxième édition) "Favoriser l'utilisation de la norme exceptions":
"Sans doute, toutes erronées méthode les invocations se résument à un illégales argument ou d'état illégales, mais d'autres les exceptions sont normalement utilisés pour certains types d'arguments et illégale états. Si un appelant passe null dans un certain nombre de paramètres dont les valeurs null sont interdits, convention dicte que NullPointerException être jeté plutôt que de IllegalArgumentException."
J'ai été en faveur de jeter IllegalArgumentException
pour les paramètres nuls, jusqu'à aujourd'hui, quand j'ai remarqué l' java.util.Objects.requireNonNull
méthode en Java 7. Avec cette méthode, au lieu de faire:
if (param == null) {
throw new IllegalArgumentException("param cannot be null.");
}
vous pouvez le faire:
Objects.requireNonNull(param);
et il va jeter un NullPointerException
si le paramètre de vous passer est null
.
Étant donné que cette méthode est bang au milieu de l' java.util
- je prendre son existence à être assez forte indication que de jeter NullPointerException
est "la Java façon de faire les choses".
Je pense que je suis décidé à n'importe quel taux.
Notez que les arguments sur dur de débogage sont fausses, parce que bien sûr, vous pouvez fournir un message d' NullPointerException
de dire ce qui était nulle et pourquoi il ne devrait pas être null. Tout comme avec IllegalArgumentException
.
Un avantage supplémentaire d' NullPointerException
, c'est que, dans très critique pour les performances de code, vous pouvez renoncer à une vérification explicite pour les nuls (et un NullPointerException
avec un sympathique message d'erreur), et s'appuient sur l' NullPointerException
vous obtiendrez automatiquement lorsque vous appelez une méthode sur le paramètre null. À condition que vous appelez une méthode rapidement (c'est à dire échouer rapidement), alors vous avez essentiellement le même effet, pas tout à fait aussi facile pour le développeur. La plupart du temps, il est probablement préférable de vérifier explicitement et de le jeter avec un message utile pour indiquer le paramètre est null, mais c'est agréable d'avoir la possibilité de changer que si les performances dicte sans casser la publication contrat de la méthode ou le constructeur.
J'ai tendance à suivre la conception de JDK bibliothèques, en particulier des Collections et de la concurrence (Joshua Bloch, Doug Lea, ces gars-là savent comment la conception solide Api). De toute façon, de nombreuses Api du JDK pro-activement jette NullPointerException.
Par exemple, la Javadoc de la Carte.containsKey états:
@throws exception NullPointerException si la clé est nulle et cette carte ne permet pas les clés null (optionnel).
Il est parfaitement valide de lancer votre propre NPE. La convention est d'inclure le nom du paramètre qui est nulle dans le message de l'exception.
Le modèle va:
public void someMethod(Object mustNotBeNull) {
if (mustNotBeNull == null) {
throw new NullPointerException("mustNotBeNull must not be null");
}
}
Quoi que vous fassiez, ne laissez pas une mauvaise valeur pour obtenir définir et lancer une exception plus tard, quand d'autres le code tente de l'utiliser. Qui rend le débogage d'un cauchemar. Vous devriez toujours suivre le "fail-fast" principe.