ant*_*res 64

因为当你捕获异常时,你应该正确处理它.而且您不能指望在代码中处理所有类型的异常.此外,当您捕获所有异常时,您可能会遇到一个异常,该异常无法处理并阻止堆栈中的代码正确处理它.

一般原则是捕捉最具体的类型.

  • 例如,当要求线程停止时,会引发java.lang.InterruptedException.如果被捕获并被忽略,则无法正常停止线程处理,并且您的代码将无法在工作线程中运行.这是一个例子,可能还有其他的例子. (11认同)
  • 我是了解他们框架的人的忠实粉丝.这个建议很糟糕的主要原因是,90%的时间,人们正在编写异常处理的代码处于其API的边界.我同意在API中,您应该始终捕获适当的异常,但是当您处于API边界时,请捕获所有不会破坏系统的内容. (4认同)

dim*_*rvp 22

简短的故事:它被称为bug掩蔽.如果你有一段代码不能正常工作并抛出异常(或者你将错误的输入传递给那段代码)而你只是通过捕获所有可能的异常而使你的眼睛失明,那么你实际上永远不会发现错误并修复它.

  • "捕捉"异常并不意味着只是继续执行,就像没有错.一个"catch"块是一段代码,你可以做**.那个****,可能是记录有关异常的信息,关于用户正在做什么或UI的状态,关闭连接和文件,以便应用程序ca优雅地退出,并通知用户发生了什么.这怎么"掩盖"什么? (3认同)
  • @user316117 `Exception` 是 Java 中所有异常的顶级类。抓住这一点意味着您抓住了所有可能的错误。你怎么知道在这样的街区该做什么?如果您想对某个错误做出反应,请捕获其特定异常并使用它。除了蒙蔽你的眼睛之外,捕获所有可能的异常没有任何实际用途(我见过很多同事这样做,因为他们想在工作日结束时回家)。 (3认同)
  • @dimitarvp Throwable 是所有异常中的顶级。它有两个子类,将异常划分为两个分支。其中之一是异常,另一个是错误。 (3认同)

Dar*_*rov 8

如果能够正确处理异常,您应该只捕获异常.由于你不能正确处理所有可能的异常,你不应该抓住它们:-)

  • 这种思维的一个主要问题是,在许多情况下,99%的可能被抛出的异常的正确处理将是报告某些行动无法完成并继续生活,但确定每一种类型如果不是不可能的话,那将是适当行动的例外将是困难的.太糟糕了,没有机制可以区分"无法满足请求"的异常,因为"CPU处于激活状态"异常. (10认同)
  • CPU 着火可能会导致某种`java.lang.Error`。 (2认同)

luj*_*jop 8

我发现 的两种可接受的用途catch(Exception)

  • 在应用程序的顶层(就在返回给用户之前)。这样你就可以提供足够的信息。
  • 使用它来将低级异常屏蔽为业务异常。

第一种情况是不言自明的,但让我来阐述第二种情况:

正在做:

try {
    // xxxx
} catch(Exception e) {
    logger.error("Error XXX",e)
}
Run Code Online (Sandbox Code Playgroud)

是像 @dimitarvp 所说的错误屏蔽。

但下面的情况有所不同:

try {
    // xxxx
} catch(Exception e) {
    throw new BusinessException("Error doing operation XXX",e)
}
Run Code Online (Sandbox Code Playgroud)

这样您就不会忽视错误并将它们隐藏在地毯下。您正在向更高的应用程序层提供高级异常和更具解释性的消息。

在正确的层管理异常也始​​终很重要。如果将低级别的异常升级到高业务层,高层实际上不可能很好地管理它。

在这种情况下,我更喜欢用业务异常来掩盖低级异常,该业务异常可以提供更好的上下文和消息,并且还具有原始异常,以便能够深入了解详细信息。

即便如此,如果你能捕获更具体的异常并为它们提供更好的处理,你就必须这样做。

如果在代码块中您可以得到 anSQLException和 a,NetworkException则您必须捕获它们并为每个代码提供足够的消息和处理。但如果在 try/catch 块的末尾你有一个Exception将其映射到 a 的方法,BusinessException那对我来说就可以了。

事实上,我发现当更高的服务层仅抛出业务异常(内部有详细信息)时就足够了。


Luc*_*ero 5

因为你真的不知道为什么会发生异常,并且有几个例外需要非常特殊的汽车才能正确处理(如果可能的话),例如OutOfMemoryException和类似的低级系统异常.

因此,您应该只捕获异常:

  • 你知道如何处理它(例如FileNotFoundException等)
  • 之后你会重新提升它们(例如进行失败后清理)
  • 何时需要将异常传输到另一个线程

  • 好吧,在这里挑剔一个 10 年前的答案:在 Java 中,“OutOfMemoryError”是一个“Throwable”,但属于“java.lang.Error”子类型。所以它不是“异常”,并且实际上不会被问题中的子句捕获。也就是说,还有一些(几乎)永远不会被捕获的“异常”,例如“NullPointerException”,它表示编程错误,并且您的点都是有效的。 (2认同)

And*_*zub 5

这取决于你需要什么。如果您需要以不同的方式处理不同类型的异常,那么您应该使用多个 catch 块并尽可能多地捕获特定的异常。

但有时您可能需要以相同的方式处理所有异常。在这种情况下 catch(Exception) 可能没问题。例如:

    try
    {
        DoSomething();
    }
    catch (Exception e)
    {
        LogError(e);
        ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user.
    }
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好的模式。日志记录不应该像这样完成,因为对于 try-catch 的每个“级别”,您将获得一堆相同的条目。 (3认同)
  • @Lucero:我认为最好有一个可以合并冗余条目的日志记录框架,而不是假设任何层处理(吞下)异常都会记录它。此外,除非异常如此之多以至于多次记录它们会造成性能瓶颈(在这种情况下我会说*这是*一个需要修复的问题)我认为日志中有冗余信息,然后可以通过一个日志查看实用程序,比拥有一个更简洁的日志更可取,后者缺少最终需要的一条信息。 (2认同)