Java 异常输出后之前语句才输出的原因是什么?

来源:互联网 发布:mac导入后删除项目 编辑:程序博客网 时间:2024/06/08 13:10
public class Run {    public static void main(String[] args) {        System.out.println("end");        throw new RuntimeException("end problem");    }}

执行结果为什么会出现异常end problem 在”end“之前输出的情况


作者:RednaxelaFX
链接:https://www.zhihu.com/question/51392452/answer/126663118
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

因为Java对stderr和stdout的flush策略不同。
题主的例子里,"end"是在System.out(也就是包装stdout的Java PrintStream对象)上输出的,而"end problem"则是在抛出异常后,由实现了Thread.UncaughtExceptionHandler接口的、main线程所关联的ThreadGroup对象的uncaughtException()方法来捕获异常并向System.err(也就是包装stderr的Java PrintStream对象)输出日志:
ThreadGroup (Java Platform SE 8 )
  • Otherwise, this method determines if the Throwable argument is an instance ofThreadDeath. If so, nothing special is done. Otherwise, a message containing the thread's name, as returned from the thread'sgetName method, and a stack backtrace, using the Throwable's printStackTrace method, is printed to the standard error stream.

所以一个在stdout上输出、一个在stderr上输出,两者之间就不保证有任何顺序关系了,哪个在前面输出都有可能。
题主要是想要保证“end"在"end problem"之前输出的话,可以在throw之前再来个System.out.flush()调用,把stdout里的内容给flush到屏幕上。

(不过我在Mac上实验题主的代码还没能复现出"end"在异常信息之后输出的情况…)

或者:写成 System.err.println("end"); 试试

原创粉丝点击