为什么运行时异常是不可恢复的?

6
在Java文档中,我看到了以下定义:“如果客户端可以合理地预期从异常中恢复,请将其设置为已检查异常。 如果客户端无法采取任何措施来从异常中恢复,请将其设置为未经检查的异常。” 未经检查的异常-争议 我不清楚“从异常中恢复”的概念是什么意思?
基于该定义,为什么NumberFormatException无法恢复? 我认为当此异常发生时,我们可以要求用户提供其他有效字符串以继续程序。 是这样吗?

1
Java教程不是“Java文档”。您引用的页面构成了反对使所有异常未经检查的论据。 - user207421
4个回答

6
如果出现开发者无法合理恢复的错误,应该使用Error,例如VerifyErrorNoMuchMethodError。如果出现我认为不可能的情况,我会使用AssertionError
如果出现开发者可能能够从中恢复的错误,尽管大多数开发者不太可能知道如何处理异常,但可以使用RuntimeException,因为这不会强制开发者编写处理代码。
如果正在将错误传递给调用者处理,即使大多数开发者不知道如何从异常中恢复,即使他们知道,也可能很难从该异常中恢复,可以使用已检查的异常。
您还可以创建一个Throwable或直接子类,它也是已检查的,但我仅将其用作打印堆栈跟踪的简单方法,即清楚地表明它实际上不是错误。建议避免抛出此类Throwable,因为它很容易混淆,并且极不可能正确处理。
在我们的代码库中,我们可能会说我们有效地使用异常,并且在许多情况下编写调用方和被调用方,这是能够以有用的方式传递异常的最佳机会。然而,通过备用方案进行恢复仅占我们catch语句的19%,而“信号”占6%的情况(“信号”是在深度调用堆栈中偶尔传递已检查异常)。总之,我们只能以我认为检查异常意图的方式处理和恢复约25%的异常/错误。我认为这是有价值的25%,但如果更高就更好了。

enter image description here

关于我们如何处理异常的不同方式的完整文章,请参见https://vanilla-java.github.io/2016/06/21/Reviewing-Exception-Handling.html


3
“恢复”意味着异常不会停止您的程序,程序可以处理异常(通过try-catch块的帮助)然后继续执行。
例如: 您正在创建一个程序来搜索员工数据库。 如果找不到特定的员工,则期望您的程序“恢复”(处理它)并允许用户查找另一个员工。 在这种情况下,您可以创建一个称为EmployeeNotFoundException的“已检查异常”。 已检查异常将提示程序员处理它(通过try-catch或使用throws)。
关于为什么NumberFormatException被设置为未检查异常: 首先,问题中提到的规则适用于用户定义的异常而不是内置异常。 它被设置为未检查异常,因为它们指示了一个“编程错误”。 在调用Integer.parseInt()之前,可能已经知道输入字符串是否是有效的整数。 因此,在尝试解析之前应该进行此检查,而不是把这个责任交给JVM。 您可以在抛出未检查异常的代码周围放置try-catch,并尝试处理它,但未检查异常的发生通常表示无法预期的问题。

NumberFormatException是编程错误,因此它是未经检查的异常...但是,ParseException和FileNotFoundException不是编程错误(因为它们是已检查的错误)?我无法区分它们之间的不同(NumberFormatException和ParseException):( - Ricky Tran
NumberFormatException是一种输入异常,如果您可以要求用户提供正确的输入,则可以恢复。 - Peter Lawrey
现在,让我举个例子:对于NumberFormatException异常,当异常发生时,我会自动将输入字符串分配为“0”(或“1”,“2”等)=> 这是恢复操作吗? - Ricky Tran

2
检查型异常背后的主要原因似乎是为了控制您何时以及在哪里处理错误。您可以立即使用try-catch处理它,或者只声明该方法会抛出异常并在更高的级别上处理它(一个或多个级别)。这也表明您可以从错误中恢复 - 否则,您为什么要关心您处理它们的位置?
NumberFormatException不是用户提供错误输入的错误,而是程序员没有预见到可能会提供无效输入的可能性,因此不可恢复;实质上,这是一个错误。
这里有更深入的异常阅读:已检查与未检查的异常。

0

你说得对,你总是可以处理异常。try-catch块存在的原因也是如此。但是处理可能导致繁琐代码库的所有可能引起代码的异常不太现实。此外,程序员在编码中出错导致RuntimeException错误的情况比用户提供的无效输入更多。

最终意味着,如果要提供的功能无法处理异常并且没有办法处理它,则将异常标记为未经检查的异常。然后由程序员决定是否处理未经检查的异常以提供某些功能。


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