Java 空结果vs为可预测但不可预防的失败引发异常
遇到可预测但不可预防的故障的方法的首选设计是什么他们应该返回空结果还是在失败时抛出异常?请解释你的理由。 我将给出两个示例方法:Java 空结果vs为可预测但不可预防的失败引发异常,java,exception,optional,Java,Exception,Optional,遇到可预测但不可预防的故障的方法的首选设计是什么他们应该返回空结果还是在失败时抛出异常?请解释你的理由。 我将给出两个示例方法: 这样的方法返回数组中某个值的索引 门票。购买(20100)。票务机器人试图用100美元购买至少20张票。该方法返回已购买的票证列表 对于这两种方法,假设用户无法预测该方法是否能成功找到匹配项 如果出现以下情况,方法1可能会失败: 数组不包含所需的值 如果出现以下情况,方法2可能会失败: 没有足够的票 有足够的票出售,但价格超过100美元 Java选择为方法1返
门票。购买(20100)
。票务机器人试图用100美元购买至少20张票。该方法返回已购买的票证列表- 数组不包含所需的值
- 没有足够的票
- 有足够的票出售,但价格超过100美元
请注意,尽管这个问题包含两个具体的方法,但我正在寻找通用的设计指南,而不是上述方法的特定解决方案。通常,您希望将返回类型设置为包含您可能需要知道的所有信息的对象 在Java的早期,返回通常无效的值是很常见的,例如
-1
(在Arrays.binarySearch()
)或null
,以表示没有值。更现代的API倾向于返回一个,以在编译时强制执行可能没有结果的概念(以及区分“无结果”和“结果为null
)
在
Tickets.buy()
示例中,您可以有一个,其中“left”值可能是购买失败的原因,“right”值可能是成功购买的票据。最佳方法取决于具体情况
案例1:
由于该方法返回已找到元素的索引,如果未找到所需的值,我建议返回-1
。请使用几乎所有人都熟悉的众所周知的API,如indexOf()
案例2:
在这里,我建议使用异常(InsufficientMoneyException
,OutOfTicketsException
,…)。空列表或null
不是很有意义,不同的错误情况不能用它反映出来。
通过这种方式,您可以在各自的catch块中正确处理异常
通常,您必须记住,抛出异常是昂贵的操作,因为必须构建堆栈跟踪。这个问题是基于观点的,就像整个返回null/抛出异常/返回空对象的困境一样 我个人认为返回
-1
是第一种方法,而为第二种方法抛出异常会更好
遵循这个原则,一种方法应该做一件事
第一种方法的目标是搜索元素,它可以找到它,也可以不找到它。这是预期的行为
第二种方法的目标是购买票证。与第一种方法不同,它不是检查是否可以购买票证,而是检查是否可以购买票证。预期的行为是购买了票证。如果该行为没有发生,则发生了错误,因此应抛出异常
我还认为@StriplingWarrior的方法可能并不理想,因为如果您有两种以上的可能情况,那么您也不可能真正有
瑞普。我花了15分钟写了一个答案,但我不小心打开了网络控制台并删除了正文。上次保存的答案大概是10分钟前。我甚至不知道你怎么会不小心这样做。我猜F12
和DEL
有点接近了我最终接受了在
我的解释如下:
- 从纯粹主义的角度来看,如果
Arrays.binarySearch()的目的
是返回数组中某个元素的索引,当找不到匹配项时,它应该抛出异常。没有结果具有负索引这一事实是一个方便的事实,它允许我们返回-1。但是,在理想情况下,此方法应该抛出异常。如果此方法能够回答问题”数组是否包含此元素并返回一个布尔值
,则无需抛出异常
Tickets.buy(20100)
假设在购买Tickets中找到匹配项。如果没有找到匹配项,则应抛出异常
也许您可以为第二个错误返回不同的错误代码one@user7这样做会阻止我在成功时返回票证列表。另外,请注意,我正在寻找一般指导原则,而不是针对我给出的特定示例的解决方案。Valid..或者,您可以在正常操作中返回列表,并可以引发以下异常:将原因(可能是enum)作为具有适当getter的实例变量(这里的异常是否有效是有争议的)关于异常是否有意义,我比较喜欢公认答案的实用主义:尝试用异常而不是返回类型实现相同的东西,看看哪些代码更清晰、更容易理解。@StriplingWarrior感谢您为我指明了这个方向。我阅读了公认的答案和下面的许多其他答案,但是最后,我发现自己更令人满意(也不那么主观)。谢谢你的建议。虽然问题中有具体的例子,但实际上我很满意