当前位置:  开发笔记 > 编程语言 > 正文

检索方法是否应返回'null'或在无法生成返回值时抛出异常?

如何解决《检索方法是否应返回'null'或在无法生成返回值时抛出异常?》经验,为你挑选了11个好方法。

我有一个方法,如果找到它,它应该返回一个对象.

如果找不到,我应该:

    返回null

    抛出一个例外

    其他

Ken.. 472

如果您总是希望找到一个值,则抛出异常(如果缺少).例外意味着存在问题.

如果该值可能丢失或存在且两者都对应用程序逻辑有效,则返回null.

更重要的是:你在代码中的其他地方做了什么?一致性很重要.



1> Ken..:

如果您总是希望找到一个值,则抛出异常(如果缺少).例外意味着存在问题.

如果该值可能丢失或存在且两者都对应用程序逻辑有效,则返回null.

更重要的是:你在代码中的其他地方做了什么?一致性很重要.


@Ken:+ 1,如果你确实抛出一个异常,但可以先验地检测它(比如HasItem(...)),那么用户应该提供所说的Has*或Contains方法.
当值丢失时,不要返回值或null,请考虑返回Maybe .请参阅http://mikehadlow.blogspot.nl/2011/01/monads-in-c-5-maybe.html.
@crush我认为指导原则是_将什么参数传递给function_。如果传递_identity_(例如您提到主键),则如果未找到该条目,则应将其视为例外,因为它表示系统中的状态不一致。示例:如果该人已被删除,则将抛出“ GetPersonById(25)”,但“ GetPeopleByHairColor(“ red”)`将返回空结果。因此,我认为参数说明了期望值。
在@ErwinRooijakkers _design选择方式中,从Java 8开始,您还可以返回[Optional ](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)

2> Carlton Jenk..:

如果确实是错误,则仅抛出异常.如果对象的预期行为不存在,则返回null.

否则这是一个偏好的问题.


我不同意.您可以将异常作为状态代码抛出:"NotFoundException"
我认为处理空情况比“ NotFoundException”要容易得多。考虑一下您必须为抛出“ NotFoundException”的每个单个检索请求编写多少行try-catch。在我看来,准备好所有这些代码很痛苦。

3> Matias Nino..:

作为一般规则,如果方法应始终返回一个对象,那么请使用异常.如果您预计偶尔会出现空值并希望以某种方式处理它,请使用null.

无论你做什么,我都强烈反对第三种选择:返回一个写着"WTF"的字符串.


我打算投票,因为WTF选项对我来说似乎很棒......但显然我有一颗心
抛出新的WtfExceptin

4> Kevin Gale..:

如果null从不指示错误,则返回null.

如果null始终是错误,则抛出异常.

如果null有时是异常,那么编写两个例程.一个例程抛出异常,另一个是布尔测试例程,它返回输出参数中的对象,如果找不到对象,则例程返回false.

很难滥用Try例程.忘记检查null是很容易的.

所以当null是你刚才写的错误时

object o = FindObject();

当null不是错误时,您可以编写类似的代码

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


在我看来,尝试方法是最好的方法.您不必查找如果无法返回对象会发生什么.使用Try方法,您可以立即知道该怎么做.

5> Lena Schimme..:

我只是想概括之前提到的选项,抛出一些新的:

    返回null

    抛出异常

    使用null对象模式

    为你的方法提供一个布尔参数,所以调用者可以选择是否要你抛出异常

    提供一个额外的参数,因此调用者可以设置一个值,如果没有找到值,他将返回该值

或者您可以组合这些选项:

提供几个重载版本的getter,这样调用者就可以决定走哪条路.在大多数情况下,只有第一个具有搜索算法的实现,而其他的只是包围第一个:

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

即使您选择只提供一个实现,您也可能希望使用这样的命名约定来阐明您的合同,如果您决定添加其他实现,它也会有所帮助.

你不应该过度使用它,但它可能是有帮助的,特别是在编写一个帮助程序类时,你将在数百个不同的应用程序中使用它们,它们具有许多不同的错误处理约定.


使用`Expected findObject(String)`可以更清晰地写出大部分内容.其中`Expected `具有函数`orNull()`,`orThrow()`,`orSupplied(Supplier 供应商) `,`或默认(T默认)`.这抽象了从错误处理中获取数据

6> pmlarocque..:

使用null对象模式或抛出异常.


如果使用空对象模式,那么如何将键映射到空对象的情况与密钥没有映射的情况区分开来?我认为返回一个没有意义的对象会比返回null更糟糕.将null返回到未准备好处理它的代码通常会导致抛出异常.不是例外的最佳选择,但仍然是例外.返回无意义的对象更可能导致代码错误地将无意义的数据视为正确.
null对象如何为实体查找行为?例如,`Person somePerson = personRepository.find("does-not-exist");`让我们假设这个方法返回ID为"不存在"的空对象.那么`somePerson.getAge()`的正确行为是什么?现在,我还不确定空对象模式是实体查找的正确解决方案.

7> dmckee..:

与您正在使用的API保持一致.



8> Corey Goldbe..:

这取决于您的语言和代码是否促进:LBYL(在您跳跃之前看)或EAFP(比请求更容易请求宽恕)

LBYL说你应该检查值(所以返回null)
EAFP说只是尝试操作并查看它是否失败(抛出异常)

虽然我同意上述..异常应该用于异常/错误条件,并且在使用检查时返回null是最好的.


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


在某些情况下,EAFP是唯一有意义的方法.例如,在并发映射/字典中,无法询问请求时是否存在映射.

9> AlanR..:

只要问自己:"这是一个特殊情况,没有找到对象"?如果预计会在程序的正常过程中发生,则可能不应该引发异常(因为它不是异常行为).

简短版本:使用异常来处理异常行为,而不是处理程序中的正常控制流.

-Alan.



10> 小智..:

抛出异常的优点:

    调用代码中的清洁控制流程. 检查null会注入一个由try/catch本机处理的条件分支.检查null并不表示你正在检查它是什么 - 你是否正在检查null是因为你正在寻找你期望的错误,或者你是否正在检查null因此你没有在downchain上进一步传递它?

    消除"null"的含义模糊. null是否代表错误或为null实际存储在值中的是什么?很难说什么时候你只有一件事情可以作出决定.

    改进了应用程序中方法行为之间的一致性 异常通常在方法签名中公开,因此您更能够理解应用程序中的方法占用的边缘情况,以及应用程序可以以可预测的方式响应的信息.

有关示例的更多说明,请参阅:http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/


+1是因为点2非常好-null的含义与未找到的含义相同。当处理动态语言(其中Null实际上可能是该函数存储/检索的对象)时,这变得尤为重要。

11> akuhn..:

例外与合同设计有关.

对象的接口实际上是两个对象之间的契约,调用者必须满足契约,否则接收者可能会因异常而失败.有两种可能的合同

1)所有输入方法都有效,在这种情况下,必须在找不到对象时返回null.

2)只有一些输入有效,即导致找到对象的输入.在这种情况下,您必须提供第二种方法,允许调用者确定其输入是否正确.例如

is_present(key)
find(key) throws Exception

IF和ONLY如果你提供第二个合同的两种方法,你可以抛出一个例外,没有找到任何东西!

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有