不需要抛出异常就能被捕获,但 IOException 会

Exception doesn't need to be thrown to be caught, but IOException does

为什么下面的代码编译正常,但被调用的方法不需要抛出ExceptionException 不是已检查的异常而不是未检查的异常吗?请澄清。

class App {
    public static void main(String[] args) {
        try {
            amethod();
            System.out.println("try ");
        } catch (Exception e) {
            System.out.print("catch ");
        } finally {
            System.out.print("finally ");
        }
        System.out.print("out ");
    }
    public static void amethod() { }
}

如果我想使用带有 IOexception 的 try catch(已检查的异常),被调用的方法需要抛出 IOException。我明白了。

import java.io.IOException;

class App {
    public static void main(String[] args) {
        try {
            amethod();
            System.out.println("try ");
        } catch (IOException e) {
            System.out.print("catch ");
        } finally {
            System.out.print("finally ");
        }
        System.out.print("out ");
    }
    public static void amethod() throws IOException { }
}

Isn't 'Exception' a checked exception and not an unchecked exception?

是的,是的。

但即使我们知道该方法本身不会抛出 Exception,代码 catch(Exception e){ 仍然可以执行。 try 块中的代码仍然可以抛出继承自 Exception 的内容。这包括 RuntimeException 及其未选中的子类。

catch(IOException e){,另一方面,只能捕获已检查的异常。 (Java 不允许多重继承,所以任何属于 IOException 的子类都不可能是 RuntimeException 的子类。)编译器可以很容易地找出 none try 块中的代码可能会抛出一个 IOException(因为任何抛出检查异常的方法都必须明确说明),这允许它标记代码。

通常会有一个编译器错误,因为 try 块永远不会抛出您有 catch 块的已检查异常,但您观察到的行为来自事实Java 语言规范在这种情况下特别对待 Exception。根据 §11.2.3:

It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass of E1, unless E1 is Exception or a superclass of Exception.

这是合理的,因为 Exception(及其超类 Throwable)也可用于捕获扩展 RuntimeException 的异常。由于运行时异常总是可能的,因此无论是否存在检查异常,编译器总是允许 Exception 出现在 catch 子句中。