天天看點

Java中的System.out.println到底是什麼,而且Java源碼中System.java的out是null,為什麼可以調用println方法?

在我們接觸Java第一個程式時,我們使用了public class和public static void main(String[]) args)以及System.out.println("Hello World")代碼,至于public class和public static void main(String[] args)的解釋,可以參考另一篇文章主類及main方法,要仔細研究該問題,請在有一定文法基礎再細看。

1. System和out

首先,System是java.lang包中的一個類,該類中定義了一個PrintStream類型的常量out,并且指派為null,如下圖。

Java中的System.out.println到底是什麼,而且Java源碼中System.java的out是null,為什麼可以調用println方法?

2. println()

Java中的System.out.println到底是什麼,而且Java源碼中System.java的out是null,為什麼可以調用println方法?

3. 模拟System.out.println()形式

Java中的System.out.println到底是什麼,而且Java源碼中System.java的out是null,為什麼可以調用println方法?

4. static問題

雖然我們實作了System.out.println類似形式方法,也可以列印輸出,實作類似的功能。但是我們定義的printlnTest是static修飾的靜态方法,static方法可以不用對象,直接調用。假如我們去掉printlnTest前修飾的static修飾符,那麼輸出結果會怎樣呢?

Java中的System.out.println到底是什麼,而且Java源碼中System.java的out是null,為什麼可以調用println方法?

5. 最終原因 

如果System.out是null的話,最後肯定是沒法調用PrintStream非靜态方法的,而且out是public static final修飾,在指派null後是沒法修改和指派的,是以out肯定是在哪裡有設定。不知道你是否有了解過Java裡native辨別符修飾的方法,native修飾的方法說明方法實作部分不在目前檔案在,而是調用C++的動态連結庫,因為Java的底層使用C++編寫的,是以在底層與系統硬體打交道時,虛拟機JVM通過C++的動态連結庫來實作和作業系統的互動。而且System類的頂部有靜态代碼塊,靜态代碼塊中有registerNative()方法,而且該靜态代碼塊會在程式加載時執行,是以系統會在程式運作前先對out進行操作,實際上out不再等于null。

Java中的System.out.println到底是什麼,而且Java源碼中System.java的out是null,為什麼可以調用println方法?