在Java中,是在代码中检查异常还是使用try-catch更好的实践方式?

6

我曾经有人告诉我,捕获所有异常并不一定是个好习惯(例如,NullPointerException)。我想知道在什么情况下这是一个好习惯,在什么情况下不是,并且为什么会是这样:D

谢谢!!

坏熊猫

7个回答

5

简而言之:

检查异常用于捕获。

未经检查的异常和错误可以留待上层处理。(这些是RuntimeExceptionError的子类)。

这是因为检查异常是“可预期”的,程序可以从中恢复。未经检查的异常是无法轻易恢复的。

Sun's tutorial说(它是关于决定何种异常应该创建,但也对另一方面有帮助 - 即使用异常时):

以下是底线指南:如果客户端可以合理地预计从异常中恢复,请将其设置为已检查异常。如果客户端无法做任何事情来从异常中恢复,请将其设置为未检查异常。


未经检查的异常是程序无法轻松恢复的异常。不,Error 是程序无法轻松恢复的异常。其他 RuntimeException 可以处理,但通常是代码中可以避免的问题,比如 NullPointerException - Powerlord

3
进一步来说,Bozho的帖子中提到,检查异常通常处理你预期会发生的异常,无论你的代码有多完美(例如:网络电缆被拔掉,你捕获了IO异常)。你声明这些方法抛出检查异常,因为其他代码必须处理如何处理这些异常。
未检查异常往往用于意外情况,例如NullPointerException经常出现,因为程序应该抛出一个检查异常,过滤数据,设置默认值等。它们是未检查的,通常是意外的,因此你不必捕获它们。
虽然这并非总是正确的,但这是一种通用的方法,尤其在Java中。

2

除了bozho的回答之外,有时候还要根据应用程序的类型来决定是否需要处理它,因为在某些情况下,您可能需要对其进行一些解决方案,而在某些情况下,您可以将其留给调用者处理或最终终止。


2
您的问题标题似乎在询问,是在代码中检查和处理错误条件更好,还是将所有内容放在try块中并在catch中处理异常更好。
如果很简单,肯定要检查错误并加以处理,而不是使用try-catch。例如,如果您可以通过检查无效输入并打印“请重试”类型的消息来处理它,那么就不需要使用try-catch。
我喜欢这样思考:如果我可以干净利落地避开由异常引起的错误,请检查可能导致错误的条件并加以处理。如果您既不能轻松检查条件,也不能轻松处理它们,请使用try-catch来处理它。

1

应该捕获不是由程序错误引起和/或可以恢复的异常,其他则不应该。

一般来说,在 Java 中应该捕获已检查异常,而RunTimeExceptions 和 Errors则不用。

空指针异常是由编程错误引起的,即缺少 null 检查,因此不应该被捕获。但是,在将其抛回之前,有时您可能还想捕获 RunTimeException 仅用于记录。


1

RuntimeExceptions(大多数情况下)可以视为“编程错误”。例如,考虑在检查堆栈是否实际包含任何元素之前从堆栈中弹出对象。在正确的实现中,应该提供一些isEmpty()方法来检查堆栈的状态。如果程序员太懒或忘记检查堆栈,则应抛出异常以指示编程错误。

这些类型的异常不应被捕获。其想法是使程序崩溃并通知程序员他的错误。

另一方面,如其他人所述,检查异常是预计程序将从中恢复的异常。虽然这在实践中听起来像一个好主意,但当您无法真正做任何事情来解决异常的原因时,就会抛出检查异常。所以最终你会得到大量样板代码(即try-catch-blocks,其异常块除了记录或打印异常原因外什么也没做)。 据我所知,没有新的编程语言支持检查异常,因为这个原因(即使是JavaFX也是如此)。


0

我总是在代码的一个关键点(通常是main方法)实现try...catch(Throwable)(Throwable代表真正的错误,应用程序在遇到这种情况后不应再执行任何操作),以便知道发生了什么并记录日志。

对于一个可运行的类或者处理单个记录的类,我也会使用try...catch(Exception)。在这种情况下,即使部分处理失败,应用程序也应该继续进行 - 我捕获异常、记录日志、中止该处理条目,然后继续进行。

经验法则是,如果你要对异常采取措施(无论是中止某些处理、运行替代例程还是继续进行,只要你知道自己在做什么),那么就应该捕获异常;如果你不打算采取措施,那就不要捕获它。

不要使用IDE的try...catch创建器来隐藏异常,而是让它将异常添加到方法签名中。


您是指错误吗?异常(Exception)/运行时异常(RuntimeException)也是可抛出的(Throwable)。 - helpermethod
是的,但错误直接从Throwable继承(如OutOfMemoryError),因此如果你捕获(Exception),你就不会捕获它们。如果你打算在应用程序短暂后离开,你应该只捕获(Throwable)。 - Ravi Wallau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接