Java輸出Hello World完美過程解析

1. 你會不會輸出”Hello World!”?

圖1

圖 2

在這裡插入圖片描述

在這裡插入圖片描述

當我們學習一門編程語言的時候,我們都會先學如何輸出Hello World!

👨:“你真的會嗎?”

👩:“會!”

👩:“以下這幾個例子,我背都給你背下來!!!!【驕傲】”

C語言

printf("Hello World!");

C++語言

cout << "Hello World!";

Golang語言:

fmt.Print("hello world!")

Java語言:

System.out.print("Hello World!");

Python語言:

print('Hello World!')

👨:“但!你真的會嗎?【邪魅一笑】。這次我賭你不會!不信?那你接著往下看~”

2. 小生拋磚引玉,歡迎指正

下面這個代碼是Java輸出Hello World的代碼,代碼沒有報錯,輸出結果正確。

在這裡插入圖片描述

我們在輸出這一行打一個斷點,並且以debug模式運行,不斷點擊下一步。

在這裡插入圖片描述

首先我們可以看到是System類調用靜態成員out,並且out是一個PrintStream對象的實例,調用這個實例的println方法,就來到如下頁面。我們可以看到這個方法傳入的是我們的Hello World字符串,並且調用print方法,再調用newLine方法。從這裡就可以看出print和println方法的區別。聰明的你應該可以猜到,沒錯,newLine方法就是換行。好的,繼續往下走~

在這裡插入圖片描述

這個時候我們進入瞭print方法。這裡也很好理解。你可以想想當我們的字符串為null的時候,你會發現輸出的是一個字符串的null,而在源碼裡面正好就是這樣的設計。緊接著,將會調用該類中的write方法。那行,我們繼續進入write方法。

在這裡插入圖片描述

進入write方法,我們會發現這裡有一個同步鎖。學過Java語法的同學應該馬上就反應到瞭,這是防止在多線程的情況下,一個字符串還未處理完,另一個字符串便進來這個方法瞭,這會導致內部的數據出現矛盾!!接著是執行一個ensureOpen方法,按照我的蹩腳英文hh,初步理解這是“確定是否打開”的意思。那我們就進去看看到底是確定什麼是否打開!

在這裡插入圖片描述

我們發現這裡有一個判斷out實例是否為null的情況,當out為null的時候,拋出一個“流關閉”的異常。結合這個提示,加上對代碼的查看,我們發現這個out實例正是輸出流對象的實例。當我們要輸出什麼內容的時候,當然要判斷輸出流對象是否為空呀。OK,這裡我們沒啥問題。

在這裡插入圖片描述

那我們就要進入整個輸出語句最重要的源代碼瞭:執行寫入。

在這裡插入圖片描述

進去之後我們發現,同樣是調用重載的write方法,傳入的參數為字符串,0以及字符串長度。接著進入該方法。

在這裡插入圖片描述

前方高能!!!
同步鎖和ensureOpen方法上面已經講過不贅述。這裡初始化變量b是0,t是0加上字符串的長度。
這個時候的t-b正好就是字符串的長度,那麼接著下去,我們會取我們一次可以寫入最大的長度t-b最小值。

  • 當最小值是我們的字符串長度的時候,我們直接獲取字符串的字符數組,讓初始變量b加上寫入的長度,這個時候我們會發現循環條件已經不成立,那麼將會結束循環;
  • 當最小值是一次可以寫入最大的長度的時候,我們直接寫入最大的長度,這時候初始變量加上寫入長度的時候,循環條件是成立的,同時我們也有字符串沒有獲取,那麼將會進入下一次循環,直到b<t不成立時退出。

同時在執行循環體的過程中,仍然需要不斷清楚緩存。

其餘的幾個方法和上面的思路比較相似,這裡將不一一贅述。

在這裡插入圖片描述

3. 總結

這裡是我個人的一點點小小的思考,我覺得程序員有三個境界,從淺到深依次是:

  • 會調用源代碼
  • 會看懂源代碼
  • 會復寫源代碼

為什麼要看源代碼呢?很多急於求成的程序員會說,別人寫好的東西,你會用就好瞭啊,你要看懂實現原理幹嘛?但我想說的是,其實看源碼的過程正是你學習代碼的過程。Java源碼經歷過二十幾年的沉淀,很多東西看似底層,但其實最考驗基礎語法的功底。博主本人現在讀大二,關於Java源碼的講解肯定有很多不夠完善的地方,但我的初衷是分享。我也希望優秀的你,在評論區給我更加寶貴的建議和意見,感謝!!

以上就是Java輸出Hello World完美過程解析的詳細內容,更多關於Java輸出Hello World的資料請關註WalkonNet其它相關文章!

推薦閱讀: