zoukankan      html  css  js  c++  java
  • 烦人的异常

    无论是否有异常处理,用任何语言编写良好的错误处理代码都是困难的。当我考虑在一个给定的程序中需要实现什么样的异常处理时,我首先将可能捕获的每个异常分类到四个bucket中的一个,我将其标记为致命的、硬骨头般突出的、烦人的、外部的。

    致命的异常不是你的错,你不能阻止它们,你也不能理智地清除它们。它们几乎总是发生,因为这一进程病入膏肓,即将摆脱痛苦。内存不足、线程中止等。捕捉这些是毫无意义的,因为你的用户代码所能做的一切都不能解决问题。就让你的“finally”块运行,并希望最好的。(或者,如果你真的很担心,快速失败和不让;在这一点上“finally”块运行,它们可能只会让事情变得更糟。但这是另一话题。)

    硬骨头般突出的异常是您自己的该死的错误,您可以阻止它们,因此它们是代码中的错误。你不应该捕获它们;这样做是在你的代码中隐藏了一个错误。相反,您应该改写您的代码,这样就不可能在第一时间发生异常,因此不需要捕获异常。这个参数是空的,类型转换是坏的,索引超出范围,你试图除以零-这些都是你本来可以很容易地避免的问题,所以首先要防止混乱,而不是试图捕获它。

    令人烦恼的异常是不幸的设计决策的结果。恼人的异常是在完全非异常的情况下抛出的,因此必须一直捕获和处理。典型的异常例子是Int32.Parse,如果给它一个不能被解析为整数的字符串,它就会抛出。但是这个方法99%的用例是转换用户输入的字符串,这可能是任何旧的东西,因此解析失败也不例外。更糟糕的是,如果不实现整个方法本身,调用者就无法提前确定其参数是否糟糕,在这种情况下,他们不需要首先调用它。这个不幸的设计决策非常令人恼火,当然,框架团队随后不久就实现了TryParse,这是正确的做法。你必须抓住令人恼火的异常,但这样做是令人恼火的。试着永远不要自己写一个抛出令人烦恼的例外的库。

    最后,外部异常看起来有点像恼人的异常,只是它们不是不幸的设计选择的结果。相反,它们是凌乱的外部现实影响到你美丽、清晰的程序逻辑的结果。考虑这个伪C#代码,例如:

    try
    {
    using ( File f = OpenFile(filename, ForReading) )
    {
    // Blah blah blah
    }
    }
    catch (FileNotFoundException)
    {
    // Handle filename not found
    }
    

    你能消除try-catch?

    if (!FileExists(filename))
    // Handle filename not found
    else
    using ( File f = ...
    

    这不是同一个程序。现在出现了“种族状况”。其他进程可能已经删除、锁定、移动或更改了文件exists和OpenFile之间的文件权限。我们能更成熟点吗?如果我们锁定文件呢?那没用。媒体可能已从驱动器中删除,网络可能已关闭…。你必须抓住一个外生的异常,因为不管你多么努力地避免它,它总是可能发生的;它是你无法控制的外生条件。

    下面总结一下:

    • 不要捕捉致命的异常;不管怎样,您都无法处理它们,并且通常会使情况变得更糟。
    • 修复代码,使其永远不会触发硬骨头般突出的异常-生产代码中永远不会发生“索引超出范围”异常。
    • 尽可能避免恼人的异常,方法是调用那些在非异常情况下抛出的恼人方法的“Try”版本。如果无法避免调用烦人的方法,请捕获其烦人的异常。
    • 始终处理表示意外外部条件的异常;通常,预测每一个可能的失败是不值得或不实际的。请尝试该操作并准备好处理异常。
  • 相关阅读:
    关于本Blog无法进行评论问题的说明
    Apusic Operamasks例子部署过程
    JVM启动参数(转)
    20070724中间件产品培训方式总结
    写Blog的意义
    磁碟機讀取光碟片時遇故障7/9
    .aspx沒有語言擴充功能8/14
    水晶報表公式的dateadd及cstr應用7/11
    中毒了:Trojar6/26
    學位英語考試通過啦8/28
  • 原文地址:https://www.cnblogs.com/yilang/p/13024252.html
Copyright © 2011-2022 走看看