简体   繁体   English

在方法中抛出未抛出声明的检查异常

[英]Thrown checked exception without throws declaration in method

The following code compiles and runs on Java 13:以下代码在 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");
    }
}

How come the throw e is allowed?为什么允许throw e

Is it specified somewhere in the JLS?它是否在 JLS 中的某处指定? I was not able to find it, perhaps I'm using wrong keywords to search.我找不到它,也许我使用了错误的关键字进行搜索。

Is the compiler smart enough to deduce that there will be no real checked exception thrown and thus allows the code to compile and run?编译器是否足够聪明,可以推断不会抛出真正的检查异常,从而允许代码编译和运行?

This is a feature that was added in Java 7. The compiler can derive the type of exception if you use a variable from the catch clause to rethrow the exception.这是在 Java 7 中添加的功能。如果您使用来自 catch 子句的变量重新引发异常,编译器可以派生异常类型。 Since you have no checked exception to be caught, it knows that e could only be RuntimeException and no throws definition is needed.由于您没有要捕获的已检查异常,因此它知道 e 只能是 RuntimeException 并且不需要 throws 定义。

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

The method:方法:

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

does not throw any checked exception , from this SO thread one can read:不抛出任何checked exception ,从这个SO 线程可以读取:

You can throw unchecked exceptions without having to declare them if you really want to.如果您真的想要,您可以抛出未经检查的异常而无需声明它们。 Unchecked exceptions extend RuntimeException.未经检查的异常会扩展 RuntimeException。

therefore there is no need to adapt the main method signature.因此无需调整main方法签名。

From the Java language specification ( §14.18 The throw Statement) one can read:Java语言规范(第 14.18 节抛出语句)可以阅读:

ThrowStatement: throw Expression; ThrowStatement:抛出表达式;

At least one of the following three conditions must be true, or a compile-time error occurs:至少以下三个条件之一必须为真,否则会发生编译时错误:

  1. The type of the Expression is an unchecked exception class (§11.1.1) or the null type (§4.1).表达式的类型是未经检查的异常 class (§11.1.1) 或 null 类型 (§4.1)。

  2. The throw statement is contained in the try block of a try statement (§14.20) and it is not the case that the try statement can throw an exception of the type of the Expression. throw 语句包含在 try 语句的 try 块中(第 14.20 节),并且 try 语句不能抛出 Expression 类型的异常。 (In this case we say the thrown value is caught by the try statement.) (在这种情况下,我们说抛出的值被 try 语句捕获。)

  3. The throw statement is contained in a method or constructor declaration and the type of the Expression is assignable (§5.2) to at least one type listed in the throws clause (§8.4.6, §8.8.5) of the declaration. throw 语句包含在方法或构造函数声明中,并且 Expression 的类型可分配(第 5.2 节)给声明的 throws 子句(第 8.4.6 节、第 8.8.5 节)中列出的至少一种类型。

The code that you have shown follows at least the first condition.您显示的代码至少遵循第一个条件。 However, let us look at the following example, where non of those three aforementioned conditions are true , namely if you do:但是,让我们看看下面的例子,其中上述三个条件都不为true ,即如果你这样做:

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

that would force you to do:这将迫使你这样做:

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

which in turn would give a compiler error:这反过来会产生编译器错误:

Unhandled exception: java.lang.Exception

at the statement throw e;在语句处throw e; . .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用从未在方法主体中抛出的 throws 子句声明检查的异常 - Declaring checked exception using throws clause that is never thrown in the body of the method 在没有抛出声明的情况下从泛型方法传播异常 - Propagating an exception from a generic method without throws declaration Rethrow异常而不添加抛出声明 - Rethrow exception without adding throws to declaration 有没有办法在不添加 throws 声明的情况下抛出异常? - Is there a way to throw an exception without adding the throws declaration? java - 在重写方法中检查'throws'的异常 - java - checked exception for 'throws' in overridden method 调用抛出Checked异常的重写方法 - Invoking overriding method that throws Checked exception 重写方法抛出接口中未定义的检查异常 - Overriding method throws checked exception not defined in interface 如果方法抛出未在方法声明中使用“throws”指定的异常,会发生什么情况 - What happens if a method throws an exception that was not specified in the method declaration with “throws” 可以为被调用方法引发的异常声明检查异常吗? - Is it okay to declare a checked exception for an exception thrown by a called method? public void 方法抛出异常 if - JUNIT 测试:不应抛出异常 - public void method throws Exception if - JUNIT test: Exception should not be thrown
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM