编译器如何理解下面 运行 的异常?

How does the compiler understand which exception to run below?

    try {
        Image image = new Image("MyComputer/Documents/Photos/estambul.jpg");

        try {
            //...

            image.print();

            throw new NullPointerException();
        } finally {
            System.out.println("FINALLY");
            image.close();
            throw new IOException();
        }
    } catch (IOException ex){
        System.out.println("IO_EXCEPTION");
        System.out.println(ex.getMessage());
    }

    System.out.println("THREAD IS CONTINUE");

这里没有抛出NullPointerException。但是,没有捕获它的 catch 块。看起来 IOException 正在压缩 NullPointerException。你的评论是什么?没看懂。

NullPointerException is not thrown here.

实际上,它是...假设代码到达了您明确抛出它的语句。

但问题是内部 try 有一个 finally 块。在 finally 块中,您明确抛出了一个 IOException。这将取代原来的异常。

行为在 JLS 14.20.2 中指定。管理您示例的文本是:

"If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:

...

  • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten)."

It looks like IOException is squashing NullPointerException.

有点。但是,我们使用非正式术语 squashing 来指代捕获和忽略异常的做法。


Then it can only handle one exception at runtime.

没错。在任何时间点,每个线程最多只能有一个“突然终止原因”。