给出(一个)带有'catch(Exception)'子句的不良事件的例子

时间:2016-01-05 20:33:40

标签: java exception-handling

这是this one的后续问题。

似乎普遍认为,做一个广泛的'捕获(例外)'是一个坏主意。

推理通常类似于“你必须正确处理异常”和“抓住你可以处理的东西”以及其他一些通用的声音参数。

这些通用的答案听起来很合理,但它们并不能让我满意。

让我具体一点。这是典型的代码,应该是“坏”。

try {
   ... do something...
} catch (Exception e) {
   log(e); //leave a trace for debugging
   return ...a value the context can deal with...
}

持怀疑态度的人仍然不相信不处理异常(这可能会炸毁整个程序),必然比以这种通用方式处理它更好。

所以我真的想要一些特定的和令人信服的示例,以及代码片段,由于一个像上面那样过于宽泛的catch子句,实际上发生了一些不好的事情。

PS:人们可以用Java以外的其他语言来思考这个问题,但是由于我需要特定的例子,这实际上是关于Java程序和JRE可能引发的特定异常。

PS2:我特别感兴趣的是Exception的例子,它实际上是java.lang.Exception的子类型,而不是更广泛的'Throwable'。因此,排除像'OutOfMemoryError'这样的东西作为有效的例子。

3 个答案:

答案 0 :(得分:6)

捕获NullPointerException可能会导致应用程序无意中忘记了所需内容尚未完成的事实。稍后应用程序将再次失败或行为异常,因为之前的操作没有完成,但现在更难以弄清楚。

在事务中吃异常可能导致事务本身不会回滚。您最终可能会得到不一致的数据。

吃顿人的异常:

public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        try {
            doSomeWork();
            Thread.sleep();
        } catch (Exception e) {
        }
    }
}

如果线程在休眠时被中断,那么当sleep方法抛出InterruptedException时,中断的标志将被重置,因为catch没有恢复中断标志,while循环条件保持为false并且线程没有出口。

类似地,因为InterruptedIOException是IOException的子类:如果您的网络IO代码只处理IOException,那么您可能无法恢复中断标志并且无法检测到您的线程已被中断。

答案 1 :(得分:0)

原因是您可能希望以不同方式处理不同的异常。

例如,在我编写的某些应用程序中,我需要告知用户确切的错误。如果我只是抓住Exception,我需要执行额外的检查以区分异常。如果我发现特定的例外,我可以很容易地做不同的事情。

如果我在文件上调用listFiles,我可能希望在发生SecurityException时显示弹出窗口,但如果发生FileNotFoundException,我可能想要打开FileChooser对话框。

编辑: 既然我在键盘上,我还应该补充一点,有时catch (Exception e)对于记录有用,但是如果你不打算处理它,那么你应该总是重新抛出那个异常。正如他们所说,一个人的垃圾是另一个人的财富。

答案 2 :(得分:0)

我会转过头来说,我认为只有这样一个过于广泛的捕获才适合的情况是,如果情况是“无论什么在这里失败,我们只是放弃”,如:

try {
   /* ... do something terribly important... */
} catch (Exception e) {
   System.err.println("We are totally screwed");
   e.printStackTrace();
   System.exit(1);
}