最近我在接受采访时询问了java中异常情况的执行顺序,如果异常没有被捕获并传播回调用代码,最后有块,那么是否打印了finally块语句? 如果是,那么它们是在异常之前还是之后打印出来的?
我尝试运行此方案,发现输出不一致。
我尝试的代码是:
public class FinallyExecution {
public static void main(String[] args) {
try{
FinallyExecution.divide(100, 0);
}finally{
System.out.println("finally in main");
}
}
public static void divide(int n, int div){
try{
int ans = n/div;
}
finally{
System.out.println("finally of divide");
}
}
}
不一致的输出是:
一次:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at exceptions.FinallyExecution.divide(FinallyExecution.java:20)
at exceptions.FinallyExecution.main(FinallyExecution.java:9)
finally of divide
finally in main
和下一个:
finally of divide
finally in main
Exception in thread "main" java.lang.ArithmeticException: / by zero
at exceptions.FinallyExecution.divide(FinallyExecution.java:20)
at exceptions.FinallyExecution.main(FinallyExecution.java:9)
那么在这种情况下究竟发生了什么? JVM是执行finally块然后以异常退出,还是以相反的顺序退出? 在任何一种情况下,为什么输出不一致?
答案 0 :(得分:1)
您正在打印到System.out
,而未捕获的异常堆栈跟踪将打印到System.err
。您可以在控制台中看到这两个内容,但未定义它的顺序。
如果您将调试打印更改为使用System.err
,则订单是一致的。