Question Une méthode de récupération doit-elle renvoyer «null» ou lancer une exception lorsqu'elle ne peut pas produire la valeur de retour? [fermé]


J'ai une méthode qui est supposée renvoyer un objet s'il est trouvé.

Si ce n'est pas trouvé, devrais-je:

  1. retourner null
  2. jeter une exception
  3. autre

437


origine


Réponses:


Si vous vous attendez toujours à trouver une valeur, lancez l'exception si elle manque. L'exception signifierait qu'il y avait un problème.

Si la valeur peut être manquante ou présente et que les deux sont valides pour la logique de l'application, renvoyez une valeur null.

Plus important: Que faites-vous d'autres endroits dans le code? La cohérence est importante.


427



Ne lancez une exception que si c'est vraiment une erreur. Si le comportement attendu de l'objet n'existe pas, renvoyez la valeur null.

Sinon, c'est une question de préférence.


91



En règle générale, si la méthode doit toujours renvoyer un objet, utilisez l'exception. Si vous anticipez le null occasionnel et que vous voulez le gérer d'une certaine manière, allez avec le null.

Quoi que vous fassiez, je déconseille fortement la troisième option: renvoyer une chaîne indiquant "WTF".


59



Si null n'indique jamais une erreur, retournez simplement null.

Si null est toujours une erreur, lancez une exception.

Si null est parfois une exception, codez deux routines. Une routine lève une exception et l'autre est une routine de test booléenne qui retourne l'objet dans un paramètre de sortie et la routine renvoie un false si l'objet n'a pas été trouvé.

Il est difficile d'abuser d'une routine Try. Il est très facile d'oublier de vérifier la nullité.

Donc, quand null est une erreur que vous écrivez

object o = FindObject();

Lorsque le null n'est pas une erreur, vous pouvez coder quelque chose comme

if (TryFindObject(out object o)
  // Do something with o
else
  // o was not found

46



Je voulais juste récapituler les options mentionnées précédemment, en en lançant de nouvelles dans:

  1. retourner null
  2. lancer une exception
  3. utilise le modèle d'objet nul
  4. fournir un paramètre booléen à votre méthode, ainsi l'appelant peut choisir s'il veut que vous lanciez une exception
  5. fournir un paramètre supplémentaire, l'appelant peut donc définir une valeur qu'il récupère si aucune valeur n'est trouvée

Ou vous pouvez combiner ces options:

Fournissez plusieurs versions surchargées de votre getter, afin que l'appelant puisse décider de la voie à suivre. Dans la plupart des cas, seul le premier a une implémentation de l'algorithme de recherche, et les autres se contentent du premier:

Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);

Même si vous choisissez de ne fournir qu’une seule implémentation, vous souhaiterez peut-être utiliser une convention de nommage comme celle-ci pour clarifier votre contrat, et cela vous aidera si vous décidez d’ajouter d’autres implémentations.

Vous ne devriez pas en abuser, mais cela peut être utile, en particulier lorsque vous écrivez une classe d'assistance que vous utiliserez dans des centaines d'applications différentes avec de nombreuses conventions de gestion des erreurs différentes.


22



Utilisez le modèle d'objet null ou lancez une exception.


18



Soyez cohérent avec les API que vous utilisez.


13



Il suffit de se demander: "est-ce un cas exceptionnel que l'objet ne soit pas trouvé"? S'il est prévu que cela se produira dans le cours normal de votre programme, vous ne devriez probablement pas déclencher une exception (car ce n'est pas un comportement exceptionnel).

Version courte: utilisez des exceptions pour gérer un comportement exceptionnel, et non pour gérer un flux de contrôle normal dans votre programme.

-Alan.


12



cela dépend si votre langue et votre code favorisent: LBYL (regarde avant de sauter) ou EAFP (plus facile de demander pardon que permission)

LBYL dit que vous devriez vérifier les valeurs (donc retourner une valeur nulle)
EAFP dit d'essayer simplement l'opération et voir si elle échoue (jeter une exception)

bien que je sois d'accord avec ce qui précède, les exceptions doivent être utilisées pour des conditions exceptionnelles / d'erreur, et le fait de renvoyer une valeur null est préférable pour les vérifications.


EAFP vs. LBYL en Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html  (Archive Web)


11