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

本文解释了在Java中,当程序同时向标准输出(System.out)和错误输出(System.err)发送消息,并且其中一个操作引发异常时,输出顺序不确定的原因。文章还提供了解决方案,确保特定消息在异常之前被输出。
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 of ThreadDeath. If so, nothing special is done. Otherwise, a message containing the thread's name, as returned from the thread's getName 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"); 试试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值