昨天遇到了一个 System.out
与 Throwable.printStackTrace()
输出信息顺序错乱的问题。
现场还原
首先我调用 System.out
输出普通字符串
1 | Time: 0.2 |
然后再调用 Throwable.printStackTrace()
输出异常信息
1 | java.lang.NoSuchMethodException: test.MathTest.ok() |
正常来说应该能得到如下输出内容
1 | Time: 0.2 |
但是有时候多运行几次代码会得到错乱的信息
1 | Time: 0.2 |
System.out
与 Throwable.printStackTrace()
的输出内容混在一起了,没有按照顺序来输出
原因
问了别人,说是因为 System.out
和 System.err
的输出顺序问题。于是查看了下 Throwable.printStackTrace()
的源码。发现 Throwable.printStackTrace()
会调用 System.err
进行内容输出
1 | public void printStackTrace() { |
再查看网上的解释,System.out
是有缓冲区的,JVM 和操作系统会等待缓冲区中的内容达到一定的大小再输出内容。而 System.err
的话,是没有缓冲区这种东西,有内容就立刻输出。所以造成了 System.out
与 Throwable.printStackTrace()
的输出内容混在一起了。这就是原因。
如何解决
根据 Throwable.printStackTrace()
的源码
1 | public void printStackTrace() { |
只需要调用 printStackTrace(PrintStream s)
传入 System.err
即可,也就是调用 Throwable.printStackTrace(System.err)
。
这样输出内容再也不会顺序错乱了。