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

时间:2015-06-09 08:08:24

标签: java exception-handling user-input

正如我从几个教程中理解的那样,实际上不应该捕获RuntimeExceptions,因为它们应该揭示方法的不适当用法,特别是API,是否正确?
此外,可以假设程序无法从RuntimeExceptions中恢复 现在,我遇到了一个由于用户输入无效而可能收到IndexOutOfBoundsException的情况:程序从HTML表单接收一个String,如果它包含整数,则要验证它。
基本上,指定的String与模式匹配,然后确定逗号的位置。之后,有必要检查逗号后面的第一个数字,以决定如何正确地舍入它。这是关键部分:

        firstDecimalChar = formattedValue.charAt(dotPosition + 1);

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

那捕获并指定要求真的那么严格吗?当然,如果位置不在界限之内,可以事先简单地检查,但我的问题是已检查未经检查的异常之间是否存在这样的直线。我想知道为什么要尽可能经常避免异常有任何技术上的缺点。 (有人提到JVM开销,但它是否显着?)

我想我需要在这里进行更深入的澄清,因为大多数教程并没有让我相信:“你根本就不应该这样做”。因为我认为在这种情况下,此异常的行为类似于已检查异常,因此很容易从中恢复。

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

4 个答案:

答案 0 :(得分:6)

  

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

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

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

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

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

碰巧,RuntimeExceptions通常与程序员错误相对应,并说"没有捕获RuntimeExceptions" 可能被视为对捕获的内容的一个很好的近似不要抓住。

当开发者决定是否延长ExceptionRuntimeException时,他/她会考虑强制客户是否合理宣布投掷条款/抓住例外。在某些情况下,异常可能是由于编程错误和正常操作引起的。错误。在这种情况下,强迫throws / catch强加给客户是不礼貌的,而且更适合将其作为RuntimeException。在客户端代码中,异常实际上用于指示"正常操作"错误,抓住它仍然是合适的。

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

答案 1 :(得分:2)

  

据我从几个教程中了解到,RuntimeExceptions是   实际上不应该被抓住,因为他们将揭示   不合理使用方法,尤其是API,是否正确?

不是真的。您始终可以捕获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);
}

答案 2 :(得分:1)

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

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

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

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

答案 3 :(得分:1)

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

Integer.isValid(String x)这样的东西可能会更好,但是标准库的丰富的本土替代品也存在问题。