为什么Java异常的stacktrace会打印在finally代码块输出之后?
问题原因说明
这个现象和finally的执行顺序无关,本质是Java不同标准输出流的缓冲刷新机制差异导致的控制台输出顺序和代码执行顺序不一致:
- 代码中
System.out.println()输出内容到System.out标准输出流 e.printStackTrace()默认把异常栈信息输出到System.err标准错误流
两个流是完全独立的,各自有独立的缓冲区,默认情况下控制台会同时展示两个流的输出,但不会严格对齐两者的输出顺序,流的刷新时机受JVM和操作系统调度影响,才会出现你看到的Line 2先于异常栈打印的情况。
实际代码的执行顺序完全符合Java语法规范:
- 执行try块代码,打印
Line 1、抛出运行时异常 - 进入catch块,调用
printStackTrace()向System.err写入异常栈内容 - 进入finally块,调用
System.out.println向System.out写入Line 2内容 - 两个流的内容先后刷新到控制台,出现顺序错位
验证方法
你可以修改catch块代码,让异常栈也输出到System.out流,就能看到符合预期的输出顺序:
catch (RuntimeException e) { e.printStackTrace(System.out); }
修改后输出会严格按照执行顺序展示:
Line 1 java.lang.RuntimeException at Scratch.main(scratch_4.java:5) Line 2 Process finished with exit code 0
内容的提问来源于stack exchange,提问作者Maksym Rybalkin
相关产品推荐
相关产品推荐

