這篇博客是爲了解釋System.out.println是什麼以及它的工做原理。java
什麼是System.out.println()小程序
System.out.println是一個Java語句,通常狀況下是將傳遞的參數,打印到控制檯。數組
public static final PrintStream out
他在啓動時就會被實例化,並與主機的標準輸出控制檯進行映射。該流在實例化以後當即打開,並準備接受數據。eclipse
System.out.println() 結構圖性能
如下是JDK源中System.out.println的骨架結構,和代碼片斷。學習
UML圖spa
部分代碼段:.net
public final class System { static PrintStream out; static PrintStream err; static InputStream in; ... } public class PrintStream extends FilterOutputStream { //out object is inherited from FilterOutputStream class public void println() { ... }
輸出重定向——改變輸出路徑命令行
’out'對象能夠自定義的。在啓動時由java運行時環境初始化,而且能夠在執行期間由開發人員更改。代替在默認狀況下的標準輸出。當您經過命令行運行程序時,輸出將打印在同一個命令窗口中。咱們可使用setOut方法來改變這種行爲。在如下示例中,我將輸出重定向到同一目錄中的文本文件。翻譯
public class ChangeOut { public static void main(String args[]) { try { System.setOut(new PrintStream(new FileOutputStream("log.txt"))); System.out.println("Now the output is redirected!"); } catch(Exception e) {} } }
System.out.println性能分析
有一個廣泛的觀念須要你們知道——System.out.println性能並很差。當咱們深刻分析時,其調用順序以下println - > print - > write()+ newLine()。這個順序流是Sun / Oracle JDK的實現。write()和newLine()都包含一個synchronized塊。同步有一點開銷,但更多的是添加字符到緩衝區和打印的開銷更大。
當咱們運行性能分析時,運行多個System.out.println並記錄時間,執行時間會按比例增長。當打印超過50個字符並打印超過50,000行時,性能降低。
固然這一切都取決於咱們使用的場景。不過不管如何請勿使用System.out.println打印日誌( logging)到stdout。
System.out.println VS 日誌記錄組件(Log4j等)
System.out.println vs loggers like Log4j
Log4J具備多種記錄級別。若是咱們正在編寫一個小程序,只是爲了實驗/學習目的那麼使用 System.out.println 就很不錯。但當咱們開發生產質量軟件時,咱們應該注意到應該使用記錄組件(log4j等),而且應該避免使用System.out.println。爲何?
因此咱們不該該使用System.out.println進行日誌記錄和調試(logging and debugging)
靜態導入來縮短System.out.println
Static Import to Shorten System.out.println()
有時咱們以爲System.out.println是一個很長的語句要打印。靜態導入可能會縮短一點,但不推薦使用,由於它致使可讀性差。我只是使用這種狀況來解釋靜態導入,並避免在下面的狀況下使用它。
import static java.lang.System.out; public class ShortSOP { public static void main(String[] args) { out.println("Hello, world"); } }
不靜態導入的話直接寫out.println會提示編譯錯誤的。
System.err和System.in
做爲相關部分,接下來介紹一下「err」和「in」。'in'與InputStream相關聯。與「out」相對,「in」用於從標準控制檯通用鍵盤獲取輸入。
'err'與PrintStream相關聯,並將參數打印到標準錯誤輸出流。當您使用eclipse等的IDE時,能夠看到「out」和「err」之間的輸出差別。
import java.io.*; /** * Created by zjl on 2017/9/16. */ public class InOutErr { public static void main(String args[]) { try { System.out.println("請輸入一段話"); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in )); String filename = reader.readLine(); InputStream input = new FileInputStream(filename); System.out.println("File opened..."); } catch (IOException e){ System.err.println("Where is that file?"); } } }
打印結果: