1

如果函数失败是正常的,例如在数据库中找不到记录或任何其他表示可能缺少值的情况,是否建议使用异常来处理这种情况?

示例伪代码:

function retrieve(foo):
  results = db.query("SELECT * FROM bar WHERE foo="+foo)
  if not results:
    throw Exception("no results")
  return results[0]

function main:
  try:
    record = retrieve(42)
  except:
    print "no record with 42"
    .... will create the record and continue
  else:
    print "record found: "+record
    .... will use the existing record and continue

另一种解决方案可能是返回空值而不是启动此异常。哪一个最有可能成为反模式?在哪些情况下使用异常更好,在哪些情况下不使用?

4

3 回答 3

3

Joshua Bloch 在“Effective Java”中总结道:

例外,顾名思义,仅用于例外情况;它们不应该用于普通的控制流

您可以在 Google 图书上找到该书的相应片段(“第 57 条:仅在特殊情况下使用例外”)。

除了异常滥用可能导致代码难以理解的原因之外,Bloch 还有一些对当今 JVM 实现有效的原因:

因为异常是为特殊情况而设计的,所以 JVM 实现者几乎没有动力让它们像显式测试一样快。

在(Hotspot)JVM 的情况下,创建异常非常昂贵(想想生成的堆栈跟踪)。

于 2013-08-26T08:20:04.663 回答
1

来自 .Net框架开发指南

如果可能,请勿将异常用于正常的控制流程。

除了系统故障和具有潜在竞争条件的操作外,框架设计者应该设计 API,以便用户可以编写不会引发异常的代码。例如,您可以提供一种在调用成员之前检查先决条件的方法,以便用户可以编写不会引发异常的代码。

用于检查另一个成员的先决条件的成员通常称为测试人员,而实际执行工作的成员称为执行者。

在某些情况下,Tester-Doer Pattern 可能会产生不可接受的性能开销。在这种情况下,应该考虑所谓的 Try-Parse 模式(有关更多信息,请参阅异常和性能)。

于 2013-08-23T10:53:02.190 回答
0

使用异常通常会导致更高的开销,滥用它们可能会减慢您的应用程序。在查询中找不到任何记录并没有什么特别的,所以我肯定会建议返回空值。

所以不,对正常控制流使用异常不是一个好习惯。

于 2013-08-23T09:06:49.740 回答