【问题标题】:Thrown checked exception without throws declaration in method在方法中抛出未抛出声明的检查异常
【发布时间】:2021-04-20 09:08:25
【问题描述】:

以下代码在 Java 13 上编译并运行:

public class CheckedExceptionSSCE {
    
    public static void main(String[] args) {
        try {
            methodNoThrowsDeclaration();
        } catch (Exception e) {
            // why is this throw allowed?
            // no throws in main()
            throw e;
        }
    }

    private static void methodNoThrowsDeclaration() {
        System.out.println("doesn't throw");
    }
}

throw e 怎么会被允许?

它是否在 JLS 中的某处指定?我没找到,可能是我搜索的关键字错误。

编译器是否足够聪明,可以推断出不会抛出真正的检查异常,从而允许代码编译和运行?

【问题讨论】:

  • 总会有某种RunTimeException

标签: java exception throw throws


【解决方案1】:

这是 Java 7 中添加的一项功能。 如果使用 catch 子句中的变量重新引发异常,编译器可以派生异常类型。由于您没有要捕获的已检查异常,因此它知道 e 只能是 RuntimeException 并且不需要 throws 定义。

更多信息: https://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html

【讨论】:

    【解决方案2】:

    方法:

    private static void methodNoThrowsDeclaration() {
            System.out.println("doesn't throw");
        }
    

    不抛出任何checked exception,从这个SO thread可以读到:

    您可以抛出未经检查的异常,而无需声明它们,如果 你真的很想。未经检查的异常会扩展 RuntimeException。

    因此无需调整main 方法签名。

    从 Java 语言规范(§14.18throw 声明)可以读到:

    ThrowStatement:抛出表达式;

    至少满足以下三个条件之一,或者 发生编译时错误:

    1. 表达式的类型是未经检查的异常类(第 11.1.1 节) 或 null 类型(第 4.1 节)。

    2. throw 语句包含在 try 语句的 try 块中 (§14.20)并且 try 语句不能抛出一个 表达式的类型除外。 (在这种情况下,我们说 抛出的值被 try 语句捕获。)

    3. throw 语句包含在方法或构造函数中 声明和表达式的类型可分配(第 5.2 节)到 at 的 throws 子句(第 8.4.6 节、第 8.8.5 节)中列出的至少一种类型 声明。

    您显示的代码至少遵循第一个条件。然而,让我们看看下面的例子,其中上述三个条件都不是true,即如果你这样做:

    private static void methodNoThrowsDeclaration() {
        System.out.println("doesn't throw");
        throw new Exception();
    }
    

    这会迫使你这样做:

    private static void methodNoThrowsDeclaration() throws Exception {
        System.out.println("doesn't throw");
        throw new Exception();
    }
    

    这反过来会导致编译器错误:

    Unhandled exception: java.lang.Exception
    

    在声明throw e;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多