看到一个有意思的题目,代码如下
public class TestCodeSeg { static { System.out.println("1"); } { System.out.println("2"); } public TestCodeSeg() { System.err.println("3"); } public static void main(String[] args) { new TestCodeSeg(); } }
求输出结果。这个有点偏,而且输出结果是不定的,但是是有规律的。
1和2顺序是不变的,因为它们是静态(类装载时被执行),3是在构造函数里。所以,程序执行顺序是静态部分然后是构造函数。但是输出结果还要收到System.out和System.err的影响。System.out是行缓冲而System.err是不缓冲,所以System.err.println("3")是立即输出。但System.out.println("1")和System.out.println("2")则因为缓冲的原因可能稍晚(但1和2的顺序不变)。具体输出结果1先2后是绝对的,但3在哪里出现跟程序执行时情况有关。如果System.err.println("3")执行时,1和2还没输出,再是则是3先:
3
3
1
2
如果1已经输出但换行符还没输出则是:
132
以此类推还有:
1
3
2
等等情况
2
如果1已经输出但换行符还没输出则是:
132
以此类推还有:
1
3
2
等等情况
标准输出和标准出错的一个区别是,标准输出往往是带缓存的,而标准出错没有缓存(默认设置,可以改)。所以如果你用标准出错打印出来的东西可以马上显示在屏幕,而标准输出打印出来的东西可能要再积累几个字符才能一起打印出来。
总的来说,System.out用于正常的输出,也就是程序真正想输出的内容。而System.err用于出错信息的输出,也就是你本来不期待看到的东西。
因此,System.err打出来的信息常常会跑到System.out信息的前面去,因为它不需要缓存。