首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异常使用异常

异常使用异常
EN

Stack Overflow用户
提问于 2009-11-20 19:00:46
回答 3查看 132关注 0票数 2

这是一个重构问题。

代码语言:javascript
复制
try
{
  string line = GetFirstLineFromFile(); //Gets first line from a text file, this line would be a number.
  int value = ConvertToInteger(line); // Gets the integer value from the string.
  int result = DivideByValue(value); // Divides some number with the value retrieved.
}
catch(Exception ex)
{
}

我主要关心的是,在这种情况下处理异常的最佳方法是什么。当然,将整个过程包装在一个try catch中就像是在说,我希望所有的东西都有一个异常。我们一定会在某个地方捕捉到一个通用异常,对吧?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-11-25 12:05:35

不要听信那些告诉你永远不应该在一个大的通用块中捕获多个异常的(成群结队的)人。在某些情况下,这是执行常规错误处理的一种完全合理的方法,这就是为什么在语言中存在这样做的能力。

将会有一些异常,您可以对它们做一些具体和有用的事情(例如,在catch块中从它们恢复)。这些是您希望单独捕获的异常类型,并且尽可能靠近它们发生的地方。

但在现实生活中,你会遇到的大多数异常都是完全意想不到的、未经检查的异常。它们是程序员错误(Bug)、断言失败、硬件故障、网络连接中断等的结果。

您应该防御性地设计您的软件,通过指定特定的“阻塞点”来处理这些不可预测的异常,并将对应用程序其余部分的干扰降至最低。(请记住,在许多情况下,“处理”异常通常意味着中止当前操作并记录错误,或者以其他方式告诉用户发生了意外错误。)

因此,例如,如果您的程序将一个文件保存到磁盘,您可以将整个保存操作包装在try块中,以捕获保存过程中出现的错误:

代码语言:javascript
复制
try {
   // attempt to perform the save operation
   doSave();

} catch (Throwable t) {
   // tell the user that the save failed for unexpected reasons
   // and log the error somewhere
   informUser("save failed!");
   log("save failed!", t);

} finally {
   // last minute cleanup (happens whether save succeeded or failed)
   ...
}

请注意,我们在这里选择了一个很好的阻塞点方法( doSave() ),然后阻止任何意想不到的错误在这一点之外进一步冒泡。阻塞点表示单个可取消的操作(保存)。尽管如果出现意外的异常,该操作显然已经结束,但无论瓶颈的另一端发生了什么,应用程序的其余部分都将保持良好状态。

还要注意,这个习惯用法并不会阻止您在doSave()中进一步处理某些异常。因此,如果有可能抛出的异常,您可以从中恢复,或者您希望以特殊的方式处理这些异常,请在doSave()中执行此操作。但对于其他的一切,你有你的瓶颈。

您甚至可能希望在main方法中为整个程序设置一个通用的未捕获异常处理程序:

代码语言:javascript
复制
public static void main(String [] args) {
    try {
       startApplication();
    } catch (Throwable t) {
       informUser("unexpected error! quitting application");
       log("fatal application error", t);
    }

但是,如果您明智地设置了其他瓶颈,就不会出现任何异常。如果希望完成常规错误处理,还可以创建UncaughtExceptionHandler并将其分配给重要线程,包括主线程或AWT线程(如果使用Swing )。

不要相信这样的教条,即你总是应该尽可能具体地捕捉异常。有时候你想要捕获和处理一个特定的异常,而另一些时候你想使用阻塞点来捕获和处理“任何其他可能出错的东西”。

票数 0
EN

Stack Overflow用户

发布于 2009-11-20 19:05:09

只是不要捕捉到“泛型异常”。

如何才能处理任何异常并知道如何保持应用程序处于干净状态?它隐藏了bug,这是一个非常糟糕的想法。

请阅读catch (Exception)上这一系列文章。

票数 2
EN

Stack Overflow用户

发布于 2009-11-20 19:09:36

您需要考虑可以从try块中的方法抛出哪些异常,以及在当前抽象级别可以处理哪些异常。

在您的例子中,我希望getFirstLineFromFile方法能够抛出您希望在这里捕获的异常。现在,您是包装并重新抛出异常,还是采取其他操作,这取决于您是否能够在此级别实际处理异常。考虑这样一种情况,您有一个可以回退到的默认文件--方法可能只是记录一个警告,然后继续使用默认文件。或者,如果整个应用程序基于读取用户提供的文件,则这更有可能是一个致命的异常,应该向上传播到顶层并传达给那里的用户。

没有像“总是抛出”或“永远不抛出”这样的硬性规则;一般来说,我认为只要有异常类型的情况不被认为是方法的正常结果,就应该抛出异常,因此无法通过方法的返回类型进行充分描述。(例如,返回boolean的isValidDbUser方法可能能够仅将SQLException处理为return false;但是返回getNumProductsRegisteredInDB的int几乎肯定会传播异常)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1769749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档