(转)何时要抛出异常?

在编写代码的过程当中,常常会遇到这样的选择,检查到一个不正常的状况,或者某个操做失败,或者检测到
某个异常,此后该怎么办?是抛出一个异常?仍是放回一个表示操做失败的返回值?

前一段在北京和小汤他们谈起这个问题的时候,有了一些粗略的想法。这段时间在 Leo4Net 的开发中,一些
想法逐步清晰起来。

=== abc ===


=== 两种方式的不一样 ===

    × 返回值很容易被检测,而捕获异常的代码则相对比较长
    × 抛出以及捕获异常须要更多的系统开销
    × 若是忽略返回值,调用者能够继续,但没有捕获的异常则将终止调用者的执行


=== 应该抛出异常的几种状况 ===
在这些状况下,应该是要抛出异常的:

    === 没法经过参数检查 ===
    
    例如空值、参数取值范围等,由于参数的规则说明是做为方法签名的一部分发布的,调用者应该很清楚
    调用这个方法所须要的参数的规格,可是调用者如今传入的错误的参数,说明调用者自己这时候极可能
    就已经出现问题了。
    
    对参数进行检查自己也是一个编写一个方法的良好习惯,这能够保证方法自己在一个相对比较稳定可知
    道状态下工做,所以方法自己将更简单也更稳定。
    
    总之,拒绝非法的参数,并抛出异常。


    === 将可能致使之后的相关功能出错 ===
    
    若是一个异常或者错误的参数将致使之后更多的异常或者之后的某个功能异常,那么不要延迟,当即抛
    出异常。

    例若有一个属性 Filename 用来保存将被保存的文件的名称,一个的方法 Save 将保存到 Filename 所
    指定的文件名中去,显然在给 Filename 属性赋值时,若是给出一个包含非法文件名字符的字符串,那
    么将致使 Save 方法中会有异常发生,不论 Save 方法是否对 Filename 再进行检查,这时候距离设定 
    Filename 的代码可能已经至关远了,所以在设定 Filename 的时候,就应该要进行这种有关的检查,
    若是文件名不合法,当即抛出异常,而不要等到之后再来发现这个问题。
    
    上述对参数进行检查其实不少也是这种状况,特别一些空值参数,将可能致使之后使用该参数的时候发
    生空值异常。
    
    
=== 不该该抛出异常的几种状况 ===

    === 不影响程序继续运行 ===
    
    若是一个错误并不影响程序逻辑的正确性,或者不影响此后代码的继续运行,那么能够没必要抛出异常。
    
    一个典型的例子例如,从集合中删除指定键值对应的元素,但指定的键值其实并不在集合中,这显然是
    一个意外状况,可是,就此继续下去,之后的程序应该还能够继续有效的运行,由于即便在正常状况下
    也不过是这个元素再也不存在于集合中而已。返回一个整数值表示删除掉的元素的个数,若是没有找到给
    定的元素,则返回0表示没有元素被删除。这个例子的另外一种情形是,当前集合元素由于某种缘由被锁住
    不能删除元素,那么应该抛出一个异常表示删除失败,而不是返回0表示没有删除元素。
    
别人评论:程序员

很是赞同。 
对于这种难以明确界定的问题,一方面有大原则,但有时候还须要视实际状况酌情处理。“将可能致使之后的相关功能出错”,个人理解是这样的:对于必定致使之后出错的状况,决定抛出异常——由于一个出错的软件接下来只能产生负面功效;对于可能出错也可能不错的状况,能够延迟抛出异常,在真正碰到错误时应该有更高层的异常捕捉,甚至平台——由于抛出异常是有代价的,若是在有但愿的时候立刻带来损失,相信有时候不可取,而若是不抛出异常会带来更大损失,也许就当即抛出了。总之,我以为软件的稳定性要求不一样,选择是有区别的。这也许是程序员的抉择——但最终是需求的抉择。 
方法始终对参数有效性进行检测——真的很重要。 
不少时候,你们想到了异常,在怎样抛出异常的话题下面,怎么详细地定义可预见的异常、尽可能避免异常产生的损失、尽可能修复和弥补,是一个稳定健壮软件必须作好的事情。开发

相关文章
相关标签/搜索