代码之家  ›  专栏  ›  技术社区  ›  fstab

对正常控制流程使用例外情况是一种不鼓励还是不鼓励的做法?

  •  1
  • fstab  · 技术社区  · 11 年前

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

    伪代码示例:

    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
    

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

    3 回复  |  直到 11 年前
        1
  •  3
  •   mdo    11 年前

    Joshua Bloch在“高效Java”中总结道:

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

    你可以在谷歌图书上找到这本书的相应片段(“第57项:仅在特殊情况下使用例外”)。

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

    因为例外是为特殊情况而设计的,所以几乎没有 激励JVM实现者使它们像显式测试一样快速。

    在(Hotspot)JVM的情况下,创建一个异常是非常昂贵的(想想生成的stacktrace)。

        2
  •  1
  •   David Osborne    11 年前

    来自.Net Framework Development Guidelines :

    如果可能的话,不要对正常的控制流程使用例外情况。

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

    用于检查另一个成员的前提条件的成员通常被称为测试人员,而实际完成工作的成员被称为实干家。

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

        3
  •  0
  •   nphx    11 年前

    使用异常通常会导致更高的开销,滥用它们可能会降低应用程序的速度。什么都没有 异常 关于在查询中找不到记录,所以我肯定建议返回null。

    所以不,对正常的控制流使用异常不是一个好的做法。