在某些情况下处理 RuntimeExceptions 有效吗?

Handling RuntimeExceptions in certain circumstances valid?

据我从几个教程中了解到,RuntimeExceptions 实际上不应该被捕获,因为它们会揭示方法的不当使用,尤其是 API,对吗?
此外,人们可能会假设该程序无法从 RuntimeExceptions 中恢复。
现在,我遇到了一种情况,由于无效的用户输入,我可能会收到 IndexOutOfBoundsException:程序从 HTML-form 接收一个 String 并想要验证它是否包含整数。
基本上分配的字符串与模式匹配,然后确定逗号的位置。之后,有必要检查逗号后面的第一个数字以确定如何正确舍入。这是关键部分:

        firstDecimalChar = formattedValue.charAt(dotPosition + 1);

如果用户输入类似“27”的内容,此语句将抛出异常。由于这是基于奇怪的用户输入,我想知道这个异常是否真的表现得像一个常见的异常(可以这么说)。
我认为这是因为在大多数教程(例如 oracle)中,他们将 checked 异常归类为无效输入导致的错误,即错误的文件路径名应该是打开,并通过一些更正或用户提示可以从该错误中恢复。同样在这里:可以简单地将上面的变量设置为零,因为这就是有人插入“27”时的意思。 -> “27.0”

catch and specify 要求真的那么严格吗?当然,如果位置没有越界,可以事先简单检查一下,但我的问题是checkedunchecked[之间是否真的有这样一条直线=31=]异常。我想知道是否有任何技术缺点为什么应该尽可能避免异常。 (有人提到 JVM 开销,但它有那么重要吗?)

我想我需要在这里做一些更深入的说明,因为大多数教程并不能说服我:"you simply shouldn't do that"。因为我认为在这种情况下,此异常的行为类似于 checked 异常,很容易从中恢复。

注意: 在我的代码中,我事先检查字符串位置是否有效并且不捕获异常 - 所以这不是这个问题的一部分:)但是这个案子让我忙不过来。

Is that catch and specify requirement really that strict?

不,我认为在某些情况下捕获未经检查的异常 (RuntimeExceptions) 是可以的。

例如,如果用户输入一个数字,我认为这样做完全没问题

double i;
try {
    i = Double.parseDouble(userInput);
} catch (NumberFormatException e) {
    addValidationError("Entered number is not valid: " + userInput);
}

如果异常是意外的并且对应于代码中的错误,请不要费心去捕获它(或者在最顶层捕获,例如在handleRequest 或其他,以及 return 例如 500 错误)。另一方面,如果您可以预见会抛出异常,(并且使用 if 语句等普通控制结构来涵盖这些情况是有问题的,例如上面的 NumberFormatException 示例)捕获它并处理它。

碰巧,RuntimeExceptions 通常对应于程序员错误,并且说 "don't catch RuntimeExceptions" 可能被视为捕获和不捕获的一个很好的近似值。

当开发者决定是否扩展ExceptionRuntimeException时he/she会考虑强制客户声​​明是否合理抛出子句/捕获异常。在某些情况下,异常可能是由于编程错误和 "normal operation" 错误引起的。在这种情况下,把throws/catch强加给客户有点不礼貌,做成RuntimeException更合适。在客户端代码中,异常实际上用于指示 "normal operation" 错误,捕获它仍然是合适的。

相关问题(但由于主要基于意见而关闭):Whosebug。com/questions/24344511/why-is-catching-a-runtimeexception-not-considered-a-good-programming-practice

As I understand it from several tutorials, RuntimeExceptions are actually not supposed to be caught, because they shall reveal inappropiate usage of methods, especially APIs, correct?

不是真的。您始终可以捕获 RuntimeException 并将其包装在已检查的 Exceptionthrow 中返回给调用者,让他们决定是终止应用程序还是以一种格式包装错误可以被用户理解

示例:

try {
    //read parameters
    String processType = args[9]; 
    String username = args[11];
    //read more parameters..
} catch (ArrayIndexOutOfBoundsException e) {
   throw new InvalidInputException("Wrong number of input parameters passed. See usage notes"+e);
}

我认为运行时异常表示在程序执行过程中不应该发生的事情。例如,IOException 不是运行时异常:IOException 发生是因为程序控制之外的某些东西(在这种情况下是文件系统)行为不端。

但是,当程序处于完全控制状态时,会发生 ArrayIndexOutOfBoundsException。所以它是一个 RuntimeException。它表示程序员做错了什么。例如数组索引的错误计算。

让我们想象一个完全不与外界交互的程序(没有 IO 等)这个程序永远不应该抛出异常,因为它完全控制发生的一切。如果确实抛出异常,则意味着程序员做错了什么(或者非常懒惰)。

注:我完全重写了这个答案,因为我首先没有看到问题末尾的注释:)

一些运行时或第三方方法(如Integer.parseInt)通过异常报告验证错误。如果我们需要这个验证功能,我们需要捕获异常。

拥有类似 Integer.isValid(String x) 的东西可能会更好,但是大量的标准库的本土替代品也存在问题。