Java API和已检查/未检查的异常混淆

Java API和已检查/未检查的异常混淆,java,exception,Java,Exception,关于检查和未检查异常的问题在这里和其他网站上被提出了数百万次,但我仍然对如此不同的答案感到困惑 在许多答案和文章中,我们可以阅读如下一般性陈述: 未经检查的运行时异常表示通常 也就是说,反映程序逻辑中的错误,并且不能 在运行时从中合理恢复 以及检查异常 在公司无法直接控制的区域内表示无效条件 程序(无效用户输入、数据库问题、网络中断、, 缺席文件) 这两条引文都来自并被多次引用 我们可以在oracle网站上看到类似的声明: 运行时异常表示的问题是由于 编程问题,因此,API客户端代码无法 合理预

关于检查和未检查异常的问题在这里和其他网站上被提出了数百万次,但我仍然对如此不同的答案感到困惑

在许多答案和文章中,我们可以阅读如下一般性陈述:

未经检查的运行时异常表示通常 也就是说,反映程序逻辑中的错误,并且不能 在运行时从中合理恢复

以及检查异常

在公司无法直接控制的区域内表示无效条件 程序(无效用户输入、数据库问题、网络中断、, 缺席文件)

这两条引文都来自并被多次引用

我们可以在oracle网站上看到类似的声明:

运行时异常表示的问题是由于 编程问题,因此,API客户端代码无法 合理预期从他们那里恢复或以任何方式处理他们 方式

让我们以使用扫描仪读取数字为例:

Scanner sc = new Scanner(System.in);
int userInput = sc.nextInt();
System.out.println(userInput);
当我键入时,即“asdf”而不是int时,nextInt()抛出InputMissMatchException。InputMissMatchException是RuntimeException,但根据上面的语句,这是检查异常“无效用户输入”的第一个示例

当我看到检查过的异常时,我甚至更加困惑。例如,NPE和FileNotFoundException——这两种情况都可以通过简单的if-else来防止,那么为什么第一个是未选中的,第二个是选中的呢

Oracle网站有一条底线指导原则:

如果可以合理预期客户从异常中恢复, 将其设置为选中的异常。如果客户端无法执行任何恢复操作 从异常中,将其设置为未选中的异常

所以根据这一点,我可以从FileNotFoundException或IOException恢复,但不能从NPE或ArrayIndexOutOfBoundsException恢复?这毫无意义


也许有人用更好的例子对此有更好的解释?

每个异常都可能在你的应用程序中恢复,也可能无法恢复。它总是取决于上下文。如果某个对象为null,并且您得到NPE(未选中),则可能会导致表达式语言表达式为空(因此在这个特定上下文中,这种情况是完全可恢复的)。另一方面,您可能会得到IOException(checked),它是不可恢复的,因为您的web应用程序无法连接到数据库,因此在这个特定web应用程序的上下文中是无用的

也许有人对此有更好的解释

有一个更好的解释:生成选中和未选中的异常只是语言作者的错误设计决策。只要java保持向后兼容,it决策就不会改变

所以只要:

  • 忽略这种人为的划分(正如其他现代语言所决定的那样)
  • 设计api时,始终使用未选中的
  • 在处理选中的异常时,将它们包装在调用堆栈的深处(您的生活会更轻松)
  • 当调用一个方法时,总是考虑/检查它可能抛出的异常(选中或未选中),并为每个异常决定是应该处理它还是重新抛出/通过

  • 简单地说,实事求是:

    • 未检查的异常(
      运行时
      类和子类)传递意外异常。 一般来说,调用方不应该知道如何处理它,在任何情况下都不会等待它。

    • 一个被检查的异常传递了一个异常,你可以把它看作是一个“正常”的异常,而调用方知道如何处理它。对他来说,这可能不是名义上的情况,但打电话的人知道这可能发生,他应该做好处理这件事的准备。

    在您的示例中:

    nextInt()在我键入例如“asdf”时抛出
    输入不匹配异常
    而不是int。
    inputmatchexception
    RuntimeException
    但是 根据上面的陈述,这是检查的第一个示例 异常“无效用户输入”

    当方法调用
    nextInt()
    时,调用方等待
    int
    值。这是例外情况。如果不是这样,用户宁愿:
    next()
    检索字符串对象,然后尝试将其转换为适合的格式。
    调用
    nextInt()
    时,调用者会按照请求等待
    int
    。强制他处理
    输入不匹配异常
    ,因为选中的
    异常
    会违反直觉


    因此,根据这一点,我可以从FileNotFoundException或 IOException但我不能从NPE或ArrayIndexOutOfBoundsException? 这毫无意义

    我认为像
    FileNotFoundException
    IOException
    这样的JDK异常都是特例。检查它们可能不一定是因为这些类的客户端等待找不到文件或流在读取或写入期间生成一些异常,而是因为流可能处于不合适的状态,因此会由于许多外部原因引发异常(文件已锁定、缺少权限、文件已移动到其他位置或无法访问的网络等…)。 生成异常的文件可能被认为是需要处理的重要内容。 因此,JDK规范更倾向于调用方显式地处理它。

    此外,在try with resources语句到达之前,调用方应该在出现异常时显式关闭流



    NPE
    ArrayIndexOutOfBoundsException
    通常是编程错误。应用程序无法进行处理来恢复它不知道存在的特定错误。那么为什么要检查这些错误呢?

    如果检查一个文件,然后将其删除,然后尝试打开它,会发生什么情况?我可以问我如何防止scanner.nextInt()中的nputMismatch。在我看来