關於System.err和System.out
先看一段測試程式碼:
多執行幾次,會發現每次的結果都不一樣:
會發現輸出的順序有時候會不一樣(要注意這裡不是重排序,重排序是針對共享變數的)。
可以先參看官方文件的描述:
/** * The "standard" output stream. This stream is already * open and ready to accept output data. Typically this stream * corresponds to display output or another output destination * specified by the host environment or user. * <p> * For simple stand-alone Java applications, a typical way to write * a line of output data is: * <blockquote><pre> * System.out.println(data) * </pre></blockquote> * <p> * See the <code>println</code> methods in class <code>PrintStream</code>. * * @see java.io.PrintStream#println() * @see java.io.PrintStream#println(boolean) * @see java.io.PrintStream#println(char) * @see java.io.PrintStream#println(char[]) * @see java.io.PrintStream#println(double) * @see java.io.PrintStream#println(float) * @see java.io.PrintStream#println(int) * @see java.io.PrintStream#println(long) * @see java.io.PrintStream#println(java.lang.Object) * @see java.io.PrintStream#println(java.lang.String) */ public final static PrintStream out = null;
/** * The "standard" error output stream. This stream is already * open and ready to accept output data. * <p> * Typically this stream corresponds to display output or another * output destination specified by the host environment or user. By * convention, this output stream is used to display error messages * or other information that should come to the immediate attention * of a user even if the principal output stream, the value of the * variable <code>out</code>, has been redirected to a file or other * destination that is typically not continuously monitored. */ public final static PrintStream err = null;
這個out和err雖然都是null,但是這兩個流是開啟狀態的,是經過JVM呼叫底層I/O。
1、System.out.println 能重定向到別的輸出流,這樣的話你在螢幕上將看不到列印的東西了, 而System.err.println只能在螢幕上實現列印,即使你重定向了也一樣。 System.setOut(new PrintStream(new FileOutputStream(new File( "c:/test.txt ")))); System.out.println( "haha "); 2、 當向控制檯輸出資訊時,開發者有兩個選擇:System.out和System.err。使用者更傾向於輸出的是System.out,而如果是 System.err則輸出“error”。儘管這看起來是顯而易見的,但很多開發者都不瞭解為什麼出錯和除錯時使用System.err。 當輸出一個流時,JVM和作業系統共同決定何時輸出這個流。也就是說,儘管開發者鍵入了: System.out.print_ ("Test Output:"); JVM和作業系統的組合體並不會立即輸出這個流。相反,它將保持等待狀態直到將要輸出的東西達到一定的量。 假設輸入以下指令: System.out.println("Debugging Info."); JVM可能同意輸出;然而,作業系統可能決定暫不輸出。 由於這個原因,在除錯程式時想要發現出錯的位置就有可能成為問題。考慮以下的程式: for(int i=0; i<56; i++) { System.out.println(i); ... // containing an error } 錯誤可能出現在i等於54時,但是可能JVM在i等於49時就結束輸出了。50到54仍然存在於快取中,結果也就丟失了。 使用System.err來報告錯誤、除錯程式就可以避免這種情況出現,它將使每一次操作的結果都輸出出來。例如以下程式: for(int i=0; i<56; i++) { System.err.println(i); ... // containing an error } 在每一次i等於54時都將顯示錯誤資訊。 3、System.out.println可能會被緩衝,而System.err.println不會 4、System.err和System.out 就是錯誤輸出和標準輸出 如果你用LOG4J記錄日誌的話,且設定錯誤等級的話 System.err的輸出是將記錄到日誌中 5、輸出裝置是一樣的 所以你看到的是一樣的 System.setErr() System.setOut() 是重定向兩個流的方法。 以下為Sun JDK1.5中文文件中的 可能有點泛泛了 ------------------------------ System.err “標準”錯誤輸出流。此流已開啟並準備接受輸出資料。 通常,此流對應於顯示器輸出或者由主機環境或使用者指定的另一個輸出目標。按照慣例,此輸出流用於顯示錯誤訊息,或者顯示那些即使使用者輸出流(變數 out 的值)已經重定向到通常不被連續監視的某一檔案或其他目標,也應該立刻引起使用者注意的其他資訊。 System.out “標準”輸出流。此流已開啟並準備接受輸出資料。通常,此流對應於顯示器輸出或者由主機環境或使用者指定的另一個輸出目標。 6、System.err.println()是要緩衝的,所以優先順序會高點,而System.out.println()是不需要緩衝的,所以優先順序會低點.