我曾经有人告诉我,捕获所有异常并不一定是个好习惯(例如,NullPointerException)。我想知道在什么情况下这是一个好习惯,在什么情况下不是,并且为什么会是这样:D
谢谢!!
坏熊猫
简而言之:
检查异常用于捕获。
未经检查的异常和错误可以留待上层处理。(这些是RuntimeException
和Error
的子类)。
这是因为检查异常是“可预期”的,程序可以从中恢复。未经检查的异常是无法轻易恢复的。
Sun's tutorial说(它是关于决定何种异常应该创建,但也对另一方面有帮助 - 即使用异常时):
以下是底线指南:如果客户端可以合理地预计从异常中恢复,请将其设置为已检查异常。如果客户端无法做任何事情来从异常中恢复,请将其设置为未检查异常。
除了bozho的回答之外,有时候还要根据应用程序的类型来决定是否需要处理它,因为在某些情况下,您可能需要对其进行一些解决方案,而在某些情况下,您可以将其留给调用者处理或最终终止。
应该捕获不是由程序错误引起和/或可以恢复的异常,其他则不应该。
一般来说,在 Java 中应该捕获已检查异常,而RunTimeExceptions 和 Errors则不用。
空指针异常是由编程错误引起的,即缺少 null 检查,因此不应该被捕获。但是,在将其抛回之前,有时您可能还想捕获 RunTimeException 仅用于记录。
RuntimeExceptions(大多数情况下)可以视为“编程错误”。例如,考虑在检查堆栈是否实际包含任何元素之前从堆栈中弹出对象。在正确的实现中,应该提供一些isEmpty()方法来检查堆栈的状态。如果程序员太懒或忘记检查堆栈,则应抛出异常以指示编程错误。
这些类型的异常不应被捕获。其想法是使程序崩溃并通知程序员他的错误。
另一方面,如其他人所述,检查异常是预计程序将从中恢复的异常。虽然这在实践中听起来像一个好主意,但当您无法真正做任何事情来解决异常的原因时,就会抛出检查异常。所以最终你会得到大量样板代码(即try-catch-blocks,其异常块除了记录或打印异常原因外什么也没做)。 据我所知,没有新的编程语言支持检查异常,因为这个原因(即使是JavaFX也是如此)。
我总是在代码的一个关键点(通常是main
方法)实现try...catch(Throwable)
(Throwable代表真正的错误,应用程序在遇到这种情况后不应再执行任何操作),以便知道发生了什么并记录日志。
对于一个可运行的类或者处理单个记录的类,我也会使用try...catch(Exception)
。在这种情况下,即使部分处理失败,应用程序也应该继续进行 - 我捕获异常、记录日志、中止该处理条目,然后继续进行。
经验法则是,如果你要对异常采取措施(无论是中止某些处理、运行替代例程还是继续进行,只要你知道自己在做什么),那么就应该捕获异常;如果你不打算采取措施,那就不要捕获它。
不要使用IDE的try...catch
创建器来隐藏异常,而是让它将异常添加到方法签名中。
Error
是程序无法轻松恢复的异常。其他RuntimeException
可以处理,但通常是代码中可以避免的问题,比如NullPointerException
。 - Powerlord