J'ai une méthode qui est censée retourner un objet s'il est trouvé.
S'il n'est pas trouvé, dois-je:
- return null
- jeter une exception
- autre
exception
error-handling
null
Robert
la source
la source
Réponses:
Si vous vous attendez toujours à trouver une valeur, lancez l'exception si elle est manquante. 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 d'application, retournez une valeur nulle.
Plus important: que faites-vous à d'autres endroits du code? La cohérence est importante.
la source
GetPersonById(25)
lancerait si cette personne a été supprimée, maisGetPeopleByHairColor("red")
retournerait un résultat vide. Donc, je pense que les paramètres disent quelque chose sur les attentes.Ne lancez une exception que si c'est vraiment une erreur. S'il est prévu que l'objet n'existe pas, renvoyez la valeur null.
Sinon, c'est une question de préférence.
la source
En règle générale, si la méthode doit toujours renvoyer un objet, optez pour l'exception. Si vous prévoyez le null occasionnel et que vous souhaitez le gérer d'une certaine manière, optez pour le null.
Quoi que vous fassiez, je déconseille fortement la troisième option: renvoyer une chaîne qui dit "WTF".
la source
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 renvoie l'objet dans un paramètre de sortie et la routine renvoie un faux 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 valeur null.
Donc, lorsque null est une erreur, vous écrivez simplement
Lorsque le null n'est pas une erreur, vous pouvez coder quelque chose comme
la source
find
etfindOrFail
de Laravel EloquentTryFindObject
méthode? Les tuples semblent plus un paradigme paresseux pour les programmeurs qui ne veulent pas prendre le temps de définir un objet qui encapsule plusieurs valeurs. C'est essentiellement tous les tuples sont de toute façon au cœur.Je voulais juste récapituler les options mentionnées précédemment, en en ajoutant de nouvelles:
Ou vous pouvez combiner ces options:
Fournissez plusieurs versions surchargées de votre getter, afin que l'appelant puisse décider de la direction à suivre. Dans la plupart des cas, seul le premier a une implémentation de l'algorithme de recherche, et les autres enveloppent simplement le premier:
Même si vous choisissez de ne fournir qu'une seule implémentation, vous souhaiterez peut-être utiliser une convention de dénomination 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, surtout 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.
la source
Expected<T> findObject(String)
oùExpected<T>
a les fonctionsorNull()
,orThrow()
,orSupplied(Supplier<T> supplier)
,orDefault(T default)
. Ceci résume l'obtention des données de la gestion des erreursUtilisez le modèle d'objet nul ou lève une exception.
la source
Person somePerson = personRepository.find("does-not-exist");
supposons que cette méthode renvoie un objet nul pour l'IDdoes-not-exist
. Quel serait alors le comportement correctsomePerson.getAge()
? Pour l'instant, je ne suis pas encore convaincu que le modèle d'objet nul soit la bonne solution pour les recherches d'entités.Soyez cohérent avec les API que vous utilisez.
la source
Avantages de lever une exception:
Pour plus d'explications avec des exemples, voir: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/
la source
cela dépend si votre langue et votre code favorisent: LBYL (regardez avant de sauter) ou EAFP (plus facile de demander pardon que de permission)
LBYL dit que vous devriez vérifier les valeurs (donc retournez une valeur nulle)
EAFP dit d'essayer simplement l'opération et de voir si elle échoue (lever 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 retourner un null est préférable lorsque vous utilisez des chèques.
EAFP vs LBYL en Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html ( Web Archive )
la source
Demandez-vous simplement: "est-ce un cas exceptionnel que l'objet ne soit pas retrouvé"? Si cela devrait se produire dans le cours normal de votre programme, vous ne devriez probablement pas lever une exception (car ce n'est pas un comportement exceptionnel).
Version courte: utilisez des exceptions pour gérer un comportement exceptionnel, pas pour gérer le flux normal de contrôle dans votre programme.
-Alan.
la source
Les exceptions sont liées à la conception par contrat.
L'interface d'un objet est en fait un contrat entre deux objets, l'appelant doit respecter le contrat ou bien le récepteur peut simplement échouer avec une exception. Il existe deux contrats possibles
1) toutes les entrées de la méthode sont valides, auquel cas vous devez retourner null lorsque l'objet n'est pas trouvé.
2) seule une entrée est valide, c'est-à-dire celle qui aboutit à un objet trouvé. Dans ce cas, vous DEVEZ proposer une seconde méthode qui permet à l'appelant de déterminer si son entrée sera correcte. Par exemple
SI et UNIQUEMENT SI vous fournissez les deux méthodes du 2e contrat, vous êtes autorisé à lever une exception si rien n'est trouvé!
la source
Je préfère simplement renvoyer une valeur nulle et compter sur l'appelant pour le gérer correctement. L'exception (faute d'un meilleur mot) est que si je suis absolument «certain», cette méthode retournera un objet. Dans ce cas, un échec est une exception et devrait être lancé.
la source
Dépend de ce que cela signifie que l'objet n'est pas trouvé.
Si c'est une situation normale, retournez null. C'est juste quelque chose qui peut arriver de temps en temps, et les appelants doivent le vérifier.
S'il s'agit d'une erreur, puis lancez une exception, les appelants doivent décider quoi faire avec la condition d'erreur de l'objet manquant.
En fin de compte, l'un ou l'autre fonctionnerait, bien que la plupart des gens considèrent généralement comme une bonne pratique de n'utiliser les exceptions que lorsque quelque chose, enfin, exceptionnel s'est produit.
la source
Voici quelques suggestions supplémentaires.
Si vous retournez une collection, évitez de renvoyer null, renvoyez une collection vide, ce qui facilite le traitement de l'énumération sans vérification null.
Plusieurs API .NET utilisent le modèle d'un paramètre thrownOnError qui donne à l'appelant le choix s'il s'agit vraiment d'une situation exceptionnelle ou non si l'objet n'est pas trouvé. Type.GetType en est un exemple. Un autre modèle courant avec BCL est le modèle TryGet où un booléen est renvoyé et la valeur est transmise via un paramètre de sortie.
Vous pouvez également prendre en compte le modèle Null Object dans certaines circonstances, qui peut être une valeur par défaut ou une version sans comportement. La clé est d'éviter les contrôles nuls dans toute la base de code. Voir ici pour plus d'informations http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
la source
Dans certaines fonctions, j'ajoute un paramètre:
True signifie throw, false signifie return some error return value. De cette façon, quiconque utilise cette fonction a les deux options. La valeur par défaut doit être vraie, pour le bénéfice de ceux qui oublient la gestion des erreurs.
la source
Renvoyer une valeur null au lieu de lever une exception et documenter clairement la possibilité d'une valeur de retour nulle dans la documentation de l'API. Si le code appelant n'honore pas l'API et ne vérifie pas le cas nul, cela entraînera très probablement une sorte d '"exception de pointeur nul" :)
En C ++, je peux penser à 3 saveurs différentes de la mise en place d'une méthode qui trouve un objet.
Option A
Renvoie null lorsqu'un objet est introuvable. Agréable et simple. J'irais avec celui-ci. Les approches alternatives ci-dessous sont destinées aux personnes qui ne détestent pas les paramédicaux.
Option B
Passez une référence à la variable qui recevra l'objet. La méthode a levé une exception lorsqu'un objet est introuvable. Cette convention est probablement plus appropriée si l'on ne s'attend pas vraiment à ce qu'un objet ne soit pas trouvé - par conséquent, vous lancez une exception pour signifier qu'il s'agit d'un cas inattendu.
Option C
La méthode renvoie false lorsqu'un objet est introuvable. L'avantage de cette option A est que vous pouvez vérifier le cas d'erreur en une seule étape claire:
la source
se référant uniquement au cas où null n'est pas considéré comme un comportement exceptionnel, je suis définitivement pour la méthode try, il est clair, pas besoin de "lire le livre" ou de "regarder avant de sauter" comme cela a été dit ici
donc en gros:
et cela signifie que le code de l'utilisateur sera également clair
la source
S'il est important que le code client connaisse la différence entre trouvé et introuvable et que cela est censé être un comportement de routine, il est préférable de renvoyer null. Le code client peut alors décider quoi faire.
la source
En général, il doit retourner null. Le code appelant la méthode doit décider de lever une exception ou de tenter autre chose.
la source
Ou retourner une option
Une option est essentiellement une classe de conteneur qui oblige le client à gérer les cas de cabine. Scala a ce concept, recherchez son API.
Ensuite, vous avez des méthodes comme T getOrElse (T valueIfNull) sur cet objet qui retournent soit l'objet trouvé, soit une alternative que le client spécifie.
la source
Je préfère retourner null -
Si l'appelant l'utilise sans vérifier, l'exception se produit de toute façon.
Si l'appelant ne l'utilise pas vraiment, ne le taxez pas a
try
/catch
blockla source
Malheureusement, JDK est incohérent, si vous essayez d'accéder à une clé non existante dans un ensemble de ressources, vous ne recevez pas d'exception et lorsque vous demandez une valeur à la carte, vous obtenez null si elle n'existe pas. Je changerais donc la réponse du gagnant comme suit, si la valeur trouvée peut être nulle, puis déclencher une exception lorsqu'elle n'est pas trouvée, sinon retourner null. Suivez donc la règle avec une exception, si vous avez besoin de savoir pourquoi la valeur n'est pas trouvée, alors toujours lever l'exception, ou ..
la source
Tant qu'il est censé renvoyer une référence à l'objet, le retour d'un NULL devrait être bon.
Cependant, si cela retourne tout le sang (comme en C ++ si vous faites: 'return blah;' plutôt que 'return & blah;' (ou 'blah' est un pointeur), alors vous ne pouvez pas retourner un NULL, car c'est pas de type 'objet'. Dans ce cas, lever une exception ou retourner un objet vide qui n'a pas d'indicateur de réussite est la façon dont j'aborderais le problème.
la source
Ne pensez pas que quiconque ait mentionné les frais généraux dans la gestion des exceptions - prend des ressources supplémentaires pour charger et traiter l'exception, donc à moins qu'il ne s'agisse d'un véritable arrêt de l'application ou d'un arrêt de processus (aller de l'avant causerait plus de mal que de bien), j'opterais pour le renvoi d'un valeur que l'environnement appelant pourrait interpréter comme bon lui semble.
la source
Je suis d'accord avec ce qui semble être le consensus ici (retourner null si "non trouvé" est un résultat normal possible, ou lever une exception si la sémantique de la situation nécessite que l'objet soit toujours trouvé).
Il existe cependant une troisième possibilité qui pourrait avoir un sens en fonction de votre situation particulière. Votre méthode peut renvoyer un objet par défaut d'une certaine sorte dans la condition "non trouvé", permettant au code appelant d'être assuré qu'il recevra toujours un objet valide sans avoir besoin de vérification nulle ou de capture d'exception.
la source
Retournez une valeur nulle, les exceptions sont exactement cela: quelque chose que votre code fait qui n'est pas prévu.
la source
Les exceptions devraient être exceptionnelles . Retourne null s'il est valide pour retourner un null .
la source
Si la méthode renvoie une collection, renvoyez une collection vide (comme indiqué ci-dessus). Mais s'il vous plaît, pas Collections.EMPTY_LIST ou autre! (en cas de Java)
Si la méthode récupère un seul objet, alors vous avez quelques options.
Soyez prudent, si vous décidez de retourner un null. Si vous n'êtes pas le seul programmeur dans le projet, vous obtiendrez NullPointerExceptions (en Java ou autre dans d'autres langues) au moment de l'exécution! Ne retournez donc pas de valeurs nulles qui ne sont pas vérifiées au moment de la compilation.
la source
null
. Voir la réponse la plus votée pour en savoir plus.Si vous utilisez une bibliothèque ou une autre classe qui lève une exception, vous devez la relancer . Voici un exemple. Example2.java est comme une bibliothèque et Example.java utilise son objet. Main.java est un exemple pour gérer cette exception. Vous devez afficher un message significatif et (si nécessaire) une trace de pile à l'utilisateur du côté appelant.
Main.java
Example.java
Example2.java
la source
Cela dépend vraiment si vous vous attendez à trouver l'objet ou non. Si vous suivez l'école de pensée selon laquelle les exceptions doivent être utilisées pour indiquer quelque chose, eh bien, euh, une exception s'est produite alors:
Sinon, retournez null.
la source