在捕获异常的地方存在歧义

Sha*_*ala 1 java exception-handling try-catch

在下面的代码中,抛出异常的位置将被捕获?

public interface MyInterface {
    public void execute() throws Exception;
}

public class MyImplementor implements MyInterface {
    public void execute() throws Exception {
        throw new MyException();
    }
}

public class MyMainClass {
    public static void main(String args[]) {
        try {
            MyImplementor temp = new MyImplementor();
            temp.execute();
        } catch(MyException e) {
            sysout("MyException");
        } catch(Exception e) {
            sysout("Exception");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(MyException是一个类扩展Exception)

那么这个例外在哪里被抓住了?此外,编译器使用什么逻辑来决定它被捕获的位置?

如果我放了

catch(Exception e)
Run Code Online (Sandbox Code Playgroud)

之前

catch(IOException e)
Run Code Online (Sandbox Code Playgroud)

它会改变控制流量吗?

Ste*_*n C 5

那么这个例外在哪里被抓住了?

在第一个处理程序中.

此外,编译器使用什么逻辑来决定它被捕获的位置?

编译器不是"决定"......

该行为由Java语言规范部分11.3指定:

"当抛出异常时,控制权从导致异常的代码转移到处理异常的try语句(§14.20)的最近的动态封闭catch子句."

(重点补充.)

换句话说,传播instanceof的异常与处理程序的声明顺序(每个处理程序的异常类型)进行比较(使用等效值).执行匹配异常的第一个.

如果我在" catch(Exception e)"之前放置" catch(IOException e)"会改变控制流量吗?

是.(假设你的意思MyException不是IOException.)这是上述行为的直接逻辑结果.


这意味着您应首先使用处理程序为最具体的异常排序处理程序.如果你弄错了,一些Java编译器和代码质量/错误检测器工具会发出警告,但这不是编译错误.