大家好,歡迎大家來到慶哥Java,我是慶哥,聽說自學Java的人都關注了我,你也趕快加入吧!歡迎~
今天,慶哥帶大家來看一個問題,就是我們寫的Java代碼到底是如何運作的?一般涉及到這樣的話題,有些人肯定會覺得,肯定又是底層,又是源碼的,應該不好了解吧,是以這裡先給大家做個聲明,這次的分享,是帶大家整體上對這個問題有一個認識,不會涉及到源碼以及很深的底層問題.!
但是保證你看了直呼過瘾,而且你們也都能看懂,畢竟慶哥的文章一直都是那麼的通俗易懂!
開始啦,首先,咱們看這樣一段代碼:
簡單吧,然後我們運作,此時我是在IDEA中将其運作:
有沒有想過,為什麼我們寫上上面的代碼,然後點選運作就能輸出列印hello呢?我們接下來找到我們寫的這段代碼的源檔案:
打開檢查一下:
沒問題,接下來我們将此段代碼複制到我們桌面,并且把代碼精簡一下,也就是成了這樣:
ok,注意我們現在已經把Hello放在了桌面上了,代碼也做了簡化,就是把注釋和包名去掉了,隻留下核心部分,到了這裡,應該沒什麼問題吧,應該都是聽得懂看的明白的吧,那好,現在問題來了,我要問你一個問題:
請問現在的Hello.java存在于哪裡?
你肯定會說,簡單啊,不是在桌面上嗎?不,我想要的不是這個答案,給你幾個選項吧:
CPU
記憶體(也就是電腦中的記憶體條)
硬碟(電腦中的磁盤,也就是你的C槽,D盤這些)
那好,現在你再來回答我,上述的Hello.java存在哪裡?我想看到這裡,應該每個人心裡都有了自己的答案吧,我覺得這并不是什麼難題,隻要你看過我之前的文章,你都能回答的對,答案就是硬碟!
我們買電腦,大部分時候也都會注意到電腦的容量大小,這裡指的就是我們的硬碟大小,比如我的就是就是1T:
那大家為什麼要在意這個呢?說的簡單點,容量大了,我可以裝的東西就多了,比如可以裝更多的軟體啊,檔案啊,比如圖檔啊,小電影啊,等等,反正電腦上的大部分東西,可下載下傳的那些都需要容量來存儲,也就是咱這磁盤是咱能接觸到的最明顯的儲存設備,比如我的E盤,大家可以看到,已經爆紅了,就是容量不多了,如果我現在想下載下傳個100G的某系列影片,那肯定裝不下了,沒容量啦,空間不夠用!
同樣的,我們寫的上述的那個Hello.java也是作為一個檔案存在于我們的電腦上,而這些東西說白了,都是存儲在我們的硬碟上,此時是存在桌面,而桌面是位于C槽下的,是以咱這檔案其實就是存在C槽中的,但是無論存儲在哪個盤,都是在我們電腦中的硬碟當中,比如我這裡的硬碟其實就是一塊1T的固态硬碟,是我後來分區成以上三個盤的,這些想必大家都懂,是以,我們寫的Hello.java檔案實質上是存儲在我們的電腦硬碟當中!
ok,到了這裡,我們搞清楚了,我們剛開始寫的這些java源檔案是存儲在哪裡,接下來我們繼續!
以上這些操作都沒什麼問題吧?這一步操作是一個編譯的過程,為什麼要這樣搞,我們緊接着看下面的操作:
上面有一個錯誤,目的是為了告訴大家,程式設計的學習要認真,不能馬虎,很多自己搞出來的錯誤都不是啥大問題,很多都是自己粗心大意造成的,記得,要認真,好了,言歸正傳,我們上面又使用了java指令去執行Hello.class檔案,最後列印輸出“hello”,什麼意思呢?
注意看了,也就是我們寫的字尾是java的叫做java源檔案,這個是我們程式員自己寫的,也就是這些代碼:
這些代碼,我們看着沒啥問題,懂點java的都知道怎麼回事,但是,對于電腦來說,它就不認識了,是以中間得有個轉換的過程,把我們認識的這些java代碼轉換成計算機可以認識的代碼,是以有這麼一張圖,大家可以看看:
就是說,我們需要把java源檔案編譯生成位元組碼檔案,也就是點class檔案,這個位元組碼檔案其實是java虛拟機識别的語言,但是我們知道,java是一種跨平台語言,所謂的跨平台主要就是由java虛拟機來實作,我們隻要把位元組碼檔案交給java虛拟機,接下來的就有虛拟機去與相應的底層作業系統打交道,去把相應的位元組碼檔案轉換成底層作業系統CPU可以執行的指令,是以,作為我們,暫時關注到位元組碼這個層面即可,也就是,你得有位元組碼,才能交給JVM去執行!
另外再給大家說兩點小知識,就是:
javac -version 檢視的是JDK的版本
java -version 檢視的則是JVM的版本
為什麼要說這個,那是因為當我們在指令行視窗執行該指令的時候:
這個時候是會啟動一個jvm虛拟機的,其實也好了解,因為我們的位元組碼檔案是需要交給jvm去執行的,現在我們這裡的操作就是要執行Hello.class位元組碼檔案的,在這裡的輸入我們可以直接省略掉字尾名class,直接輸入“java Hello”即可!
到了這裡我又必須問你一個新的問題了,你說這個Hello.class檔案是存儲在哪裡的?
其實答案顯而易見啊,必須還是我們的電腦硬碟中的,也就是此時我們寫的java源檔案Hello.java以及我們編譯生成的位元組碼檔案Hello.class都是存儲在我們的電腦桌面,實質就是電腦硬碟當中!
到了這裡我就必須在給你們來點幹貨知識了,你要記住以下這句話:
我們寫的程式,要想運作,最終必須加載進記憶體中,才能被CPU調取執行,而且所有的程式在記憶體中都是以二進制的形式存在的!
咋樣,對以上描述有疑惑嗎?
那現在,我們是不是有了位元組碼檔案,于是我們執行“java Hello”去執行該位元組碼檔案,這裡的過程需要再次強調下,也就是說,當我們在指令行視窗去執行java指令的時候,實際上就會啟動一個jvm虛拟機,在電腦中是一個程序形式存在的,也就是一旦執行“java”指令,測試就啟動了一個jvm程序,此前我們說過了,位元組碼是jvm能夠識别的語言,此時這個jvm就是用來執行我們的這些位元組碼檔案的!
這個時候jvm就會把位元組碼中的相關類加載進我們的記憶體中去,這就是類加載器在起作用,想必這個類加載器的概念,大家一定不陌生吧,也就是此時,原本在我們電腦硬碟中的位元組碼檔案通過java指令啟動的jvm,将其加載進記憶體中去了,你要知道,我們的java代碼都是由一個個的類組成的,是以此時就由jvm将我們的位元組碼class檔案加載進記憶體中了,這其中的具體轉換細節暫不讨論!
這裡可以稍微透露一下,其實jvm有自己的一套位元組碼執行引擎,jvm就會基于自己的位元組碼執行引擎,去執行加載進記憶體的那些類了,我們知道,我們的java代碼必須有一個主入口,也就是一個“main()”方法,jvm就是從這個main方法開始執行代碼,然後一步步的執行下去,需要哪個類,就會使用類加載器去加載對應的類,因為我們之前的所有java源檔案已經被編譯生成位元組碼檔案了,需要啥類都直接從這個點class檔案中加載即可。
當然,以上内容目前隻需了解即可,你隻要記住,是jvm把位元組碼檔案從硬碟加載進記憶體中即可!
ok,以上就是我這次要給大家分享的全部内容了,到了這裡,也許你會發現,其實整個文章并沒有什麼高深莫測的東西,可以說都是一些比較基礎的東西,但是我相信,很多人是沒有把這些基礎的東西給串聯起來的,也沒有思考過,我們寫的代碼,剛開始是存儲在哪,又是怎樣被加載運作的,一步步的,抽絲剝繭,雖然簡單,但是總歸也會讓你有所收獲!
你說是嗎?
好啦,這裡是慶哥Java,一個隻講Java幹貨的硬核平台,我是你們的慶哥,我們下期再見!