通俗易懂!我們寫的Java代碼到底是如何運行的?

慶哥Java 2021-08-15 14:15:05 阅读数:880

本文一共[544]字,预计阅读时长:1分钟~
通俗易懂 通俗 易懂 java 到底是

大家好,歡迎大家來到慶哥Java,我是慶哥,聽說自學Java的人都關注了我,你也趕快加入吧!歡迎~

今天,慶哥帶大家來看一個問題,就是我們寫的Java代碼到底是如何運行的?一般涉及到這樣的話題,有些人肯定會覺得,肯定又是底層,又是源碼的,應該不好理解吧,所以這裏先給大家做個聲明,這次的分享,是帶大家整體上對這個問題有一個認識,不會涉及到源碼以及很深的底層問題.!

但是保證你看了直呼過癮,而且你們也都能看懂,畢竟慶哥的文章一直都是那麼的通俗易懂!


開始啦,首先,咱們看這樣一段代碼:

public class Hello {

public static void main(String[] args) {

System.out.println("hello");
}
}

簡單吧,然後我們運行,此時我是在IDEA中將其運行:
image.png
有沒有想過,為什麼我們寫上上面的代碼,然後點擊運行就能輸出打印hello呢?我們接下來找到我們寫的這段代碼的源文件:

image.png

打開檢查一下:

image.png

沒問題,接下來我們將此段代碼複制到我們桌面,並且把代碼精簡一下,也就是成了這樣:

image.png

ok,注意我們現在已經把Hello放在了桌面上了,代碼也做了簡化,就是把注釋和包名去掉了,只留下核心部分,到了這裏,應該沒什麼問題吧,應該都是聽得懂看的明白的吧,那好,現在問題來了,我要問你一個問題:

請問現在的Hello.java存在於哪裏?

你肯定會說,簡單啊,不是在桌面上嗎?不,我想要的不是這個答案,給你幾個選項吧:

  1. CPU
  2. 內存(也就是電腦中的內存條)
  3. 硬盤(電腦中的磁盤,也就是你的C盤,D盤這些)

那好,現在你再來回答我,上述的Hello.java存在哪裏?我想看到這裏,應該每個人心裏都有了自己的答案吧,我覺得這並不是什麼難題,只要你看過我之前的文章,你都能回答的對,答案就是硬盤!

我們買電腦,大部分時候也都會注意到電腦的容量大小,這裏指的就是我們的硬盤大小,比如我的就是就是1T:
image.png

那大家為什麼要在意這個呢?說的簡單點,容量大了,我可以裝的東西就多了,比如可以裝更多的軟件啊,文件啊,比如圖片啊,小電影啊,等等,反正電腦上的大部分東西,可下載的那些都需要容量來存儲,也就是咱這磁盤是咱能接觸到的最明顯的存儲設備,比如我的E盤,大家可以看到,已經爆紅了,就是容量不多了,如果我現在想下載個100G的某系列影片,那肯定裝不下了,沒容量啦,空間不够用!

同樣的,我們寫的上述的那個Hello.java也是作為一個文件存在於我們的電腦上,而這些東西說白了,都是存儲在我們的硬盤上,此時是存在桌面,而桌面是比特於C盤下的,所以咱這文件其實就是存在C盤中的,但是無論存儲在哪個盤,都是在我們電腦中的硬盤當中,比如我這裏的硬盤其實就是一塊1T的固態硬盤,是我後來分區成以上三個盤的,這些想必大家都懂,所以,我們寫的Hello.java文件實質上是存儲在我們的電腦硬盤當中!

ok,到了這裏,我們搞清楚了,我們剛開始寫的這些java源文件是存儲在哪裏,接下來我們繼續!

image.png

以上這些操作都沒什麼問題吧?這一步操作是一個編譯的過程,為什麼要這樣搞,我們緊接著看下面的操作:

image.png

上面有一個錯誤,目的是為了告訴大家,編程的學習要認真,不能馬虎,很多自己搞出來的錯誤都不是啥大問題,很多都是自己粗心大意造成的,記得,要認真,好了,言歸正傳,我們上面又使用了java指令去執行Hello.class文件,最後打印輸出“hello”,什麼意思呢?

注意看了,也就是我們寫的後綴是java的叫做java源文件,這個是我們程序員自己寫的,也就是這些代碼:

public class Hello {

public static void main(String[] args) {

System.out.println("hello");
}
}

這些代碼,我們看著沒啥問題,懂點java的都知道怎麼回事,但是,對於電腦來說,它就不認識了,所以中間得有個轉換的過程,把我們認識的這些java代碼轉換成計算機可以認識的代碼,所以有這麼一張圖,大家可以看看:

image.png
就是說,我們需要把java源文件編譯生成字節碼文件,也就是點class文件,這個字節碼文件其實是java虛擬機識別的語言,但是我們知道,java是一種跨平臺語言,所謂的跨平臺主要就是由java虛擬機來實現,我們只要把字節碼文件交給java虛擬機,接下來的就有虛擬機去與相應的底層操作系統打交道,去把相應的字節碼文件轉換成底層操作系統CPU可以執行的指令,所以,作為我們,暫時關注到字節碼這個層面即可,也就是,你得有字節碼,才能交給JVM去執行!

另外再給大家說兩點小知識,就是:

  1. javac -version 查看的是JDK的版本
  2. java -version 查看的則是JVM的版本

為什麼要說這個,那是因為當我們在命令行窗口執行該指令的時候:

image.png

這個時候是會啟動一個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幹貨的硬核平臺,我是你們的慶哥,我們下期再見!

版权声明:本文为[慶哥Java]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/08/20210815141454118u.html