你們好,歡迎你們來到慶哥Java,我是慶哥,據說自學Java的人都關注了我,你也趕快加入吧!歡迎~java
今天,慶哥帶你們來看一個問題,就是咱們寫的Java代碼究竟是如何運行的?通常涉及到這樣的話題,有些人確定會以爲,確定又是底層,又是源碼的,應該很差理解吧,因此這裏先給你們作個聲明,此次的分享,是帶你們總體上對這個問題有一個認識,不會涉及到源碼以及很深的底層問題.!程序員
可是保證你看了直呼過癮,並且大家也都能看懂,畢竟慶哥的文章一直都是那麼的通俗易懂!編程
開始啦,首先,我們看這樣一段代碼:markdown
public class Hello { public static void main(String[] args) { System.out.println("hello"); } }
簡單吧,而後咱們運行,此時我是在IDEA中將其運行:
有沒有想過,爲何咱們寫上上面的代碼,而後點擊運行就能輸出打印hello呢?咱們接下來找到咱們寫的這段代碼的源文件:jvm
打開檢查一下:ide
沒問題,接下來咱們將此段代碼複製到咱們桌面,而且把代碼精簡一下,也就是成了這樣:學習
ok,注意咱們如今已經把Hello放在了桌面上了,代碼也作了簡化,就是把註釋和包名去掉了,只留下核心部分,到了這裏,應該沒什麼問題吧,應該都是聽得懂看的明白的吧,那好,如今問題來了,我要問你一個問題:測試
請問如今的Hello.java存在於哪裏?操作系統
你確定會說,簡單啊,不是在桌面上嗎?不,我想要的不是這個答案,給你幾個選項吧:命令行
那好,如今你再來回答我,上述的Hello.java存在哪裏?我想看到這裏,應該每一個人內心都有了本身的答案吧,我以爲這並非什麼難題,只要你看過我以前的文章,你都能回答的對,答案就是硬盤!
咱們買電腦,大部分時候也都會注意到電腦的容量大小,這裏指的就是咱們的硬盤大小,好比個人就是就是1T:
那你們爲何要在乎這個呢?說的簡單點,容量大了,我能夠裝的東西就多了,好比能夠裝更多的軟件啊,文件啊,好比圖片啊,小電影啊,等等,反正電腦上的大部分東西,可下載的那些都須要容量來存儲,也就是咱這磁盤是咱能接觸到的最明顯的存儲設備,好比個人E盤,你們能夠看到,已經爆紅了,就是容量很少了,若是我如今想下載個100G的某系列影片,那確定裝不下了,沒容量啦,空間不夠用!
一樣的,咱們寫的上述的那個Hello.java也是做爲一個文件存在於咱們的電腦上,而這些東西說白了,都是存儲在咱們的硬盤上,此時是存在桌面,而桌面是位於C盤下的,因此咱這文件其實就是存在C盤中的,可是不管存儲在哪一個盤,都是在咱們電腦中的硬盤當中,好比我這裏的硬盤其實就是一塊1T的固態硬盤,是我後來分區成以上三個盤的,這些想必你們都懂,因此,咱們寫的Hello.java文件實質上是存儲在咱們的電腦硬盤當中!
ok,到了這裏,咱們搞清楚了,咱們剛開始寫的這些java源文件是存儲在哪裏,接下來咱們繼續!
以上這些操做都沒什麼問題吧?這一步操做是一個編譯的過程,爲何要這樣搞,咱們緊接着看下面的操做:
上面有一個錯誤,目的是爲了告訴你們,編程的學習要認真,不能馬虎,不少本身搞出來的錯誤都不是啥大問題,不少都是本身粗枝大葉形成的,記得,要認真,好了,言歸正傳,咱們上面又使用了java指令去執行Hello.class文件,最後打印輸出「hello」,什麼意思呢?
注意看了,也就是咱們寫的後綴是java的叫作java源文件,這個是咱們程序員本身寫的,也就是這些代碼:
public class Hello { public static void main(String[] args) { System.out.println("hello"); } }
這些代碼,咱們看着沒啥問題,懂點java的都知道怎麼回事,可是,對於電腦來講,它就不認識了,因此中間得有個轉換的過程,把咱們認識的這些java代碼轉換成計算機能夠認識的代碼,因此有這麼一張圖,你們能夠看看:
就是說,咱們須要把java源文件編譯生成字節碼文件,也就是點class文件,這個字節碼文件實際上是java虛擬機識別的語言,可是咱們知道,java是一種跨平臺語言,所謂的跨平臺主要就是由java虛擬機來實現,咱們只要把字節碼文件交給java虛擬機,接下來的就有虛擬機去與相應的底層操做系統打交道,去把相應的字節碼文件轉換成底層操做系統CPU能夠執行的指令,因此,做爲咱們,暫時關注到字節碼這個層面便可,也就是,你得有字節碼,才能交給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乾貨的硬核平臺,我是大家的慶哥,咱們下期再見!