Java 在某些情况下处理运行时异常有效吗?

Java 在某些情况下处理运行时异常有效吗?,java,exception-handling,user-input,Java,Exception Handling,User Input,正如我从几个教程中了解到的,运行时异常实际上不应该被捕获,因为它们会揭示方法的不当使用,尤其是API,对吗? 此外,可能会假设程序无法从运行时异常中恢复。 现在,我遇到了一个案例,由于用户输入无效,我可能会收到IndexOutOfBoundsException:程序从HTML表单接收字符串,并希望验证它是否包含整数。 基本上,指定的字符串与模式匹配,然后确定逗号的位置。之后,有必要检查逗号后面的第一个数字,以决定如何正确地将其四舍五入。这是关键部分: firstDecimalCh

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

        firstDecimalChar = formattedValue.charAt(dotPosition + 1);
如果用户输入类似“27”的内容,此语句将引发异常。由于这是基于奇怪的用户输入的事实,我想知道此异常的行为是否真的类似于常见异常(可以这么说)。
我认为这是因为在大多数教程(例如)中,他们将检查过的异常归类为无效输入导致的错误,即错误的文件路径名应打开,经过一些更正或用户提示,可以从该错误中恢复。这里也一样:可以简单地将上述变量设置为零,因为当有人插入“27”->“27.0”时,这就是它的意思

捕获和指定的要求真的那么严格吗?当然,我们可以事先简单地检查位置是否超出范围,但我的问题是,在检查的异常和未检查的异常之间是否真的存在这样一条直线。我想知道为什么应该尽可能多地避免异常,是否存在任何技术上的缺点。(有人提到JVM开销,但有那么大吗?)

我想我需要一些更深入的澄清,因为大多数教程都没有说服我:“你根本不应该那样做”。因为我认为在这种情况下,这个异常的行为就像一个检查过的异常,很容易从中恢复

注意:在我的代码中,我会事先检查字符串位置是否有效,并且不会捕获异常-因此这不是问题的一部分:),但这种情况仍然让我很忙

捕获和指定的要求真的那么严格吗

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

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

double i;
try {
    i = Double.parseDouble(userInput);
} catch (NumberFormatException e) {
    addValidationError("Entered number is not valid: " + userInput);
}
如果异常是意外的,并且与代码中的错误相对应,则不要费心捕捉它(或者在最顶层捕捉,例如在
handleRequest
或其他任何级别,并返回一个500错误)。另一方面,如果您可以预见将抛出异常,(使用普通的控制结构,例如
if
语句来覆盖这些情况是有问题的,例如在上面的
NumberFormatException
示例中)捕获并处理它

事实上,RuntimeExceptions通常对应于程序员错误,说“不要捕获RuntimeExceptions”可能被看作是捕获什么和不捕获什么的一个很好的近似值

当开发人员决定是扩展
Exception
还是
RuntimeException
时,他/她会考虑强制客户端声明抛出子句/捕获异常是否合理。在某些情况下,异常可能是由于编程错误和“正常操作”错误引起的。在这种情况下,将
抛出
/
捕获
强加于客户端是不礼貌的,更适合将其设置为
运行时异常
。在客户机代码中,异常实际上是用来表示“正常操作”错误的,捕获它仍然是合适的

相关问题(但主要以观点为基础):stackoverflow.com/questions/24344511/why-is-catching-a-runtimeexception-not-signed-a-good-programming-practice

正如我从几个教程中了解到的,运行时异常是 实际上不应该被抓住,因为他们会暴露出来 方法使用不当,尤其是API,对吗

不是真的。您始终可以捕获
运行时异常
并将其包装为选中的
异常
,然后
将其扔回调用方,以便调用方决定是终止应用程序还是以用户可以理解的格式包装错误

例如:

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。因此,这是一个运行时异常。这意味着程序员做错了什么。例如,数组索引计算错误

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


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

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


最好使用类似于
Integer.isValid(String x)
的东西,但是大量的标准库的本地替换也有问题

我真的不喜欢Java无法在不引发异常的情况下检查字符串是否为整数。字符串验证是无效的