在 Java 語言白皮書上面有這樣一段話:
Java 是一種簡單的,物件導向的,適用於網路應用的,平台無關的,解釋的,健壯的,安全的,結構自然的,可移植的,高效能的,多執行緒的,動態的語言。
就單從平台無關這一點上面來說,就已經超越 C/C++ 一大截了。就比如說我們在 Windows 下面寫出來的一段 Java 程式,換成 Linux,macOS 系統裡面,一樣可以正常執行並且輸出相同的結果,但是這一點,換成 C/C++ 卻很難辦到。那麼跨平台的特性,就是 JVM 決定的了。
JVM 的專業解釋如下:
Java 虛擬機器(Java Virtual Machine,簡稱 JVM)是一種用於計算裝置的規範,它是一個虛構出來的計算機,是通過在實際的計算機上模擬模擬各種計算機功能來實現的。Java 虛擬機器包括一套位元組碼指令集、一組暫存器、一個棧、一個垃圾回收堆和一個儲存方法域。JVM 遮蔽了與具體作業系統平台相關的資訊,使 Java 程式只需生成在 Java 虛擬機器上執行的目的碼(位元組碼),就可以在多種平台上不加修改地執行。JVM 在執行位元組碼時,實際上最終還是把位元組碼解釋成具體平台上的機器指令執行。
上面的解釋看不懂也比較正常,本來不想把專業解釋放上來的,想了想還是算了,畢竟還是要讓大家對 JVM 有一點詳細的認識。如果看不懂專業解釋的話,我就用大白話給大家說:
JVM,也就是 Java 虛擬機器,就是一個平台,包含於 JRE 的下面。當你需要執行某個 Java 程式時,由 JVM 幫你進行編譯和執行。我們編寫的 Java 原始碼,編譯後會生成一種 .class 檔案,稱為位元組碼檔案。Java 虛擬機器就是負責將位元組碼檔案翻譯成特定平台下的機器碼然後執行。
而且,如圖 1 所示,JVM 分為很多個系統版本的,你編寫好的 Java 程式,無論到哪個平台上,Windows 也好,Linux 也好,macOS 也好,只需要找到 JVM,便可以成功編譯和執行。也就是說,只要在不同平台上安裝對應的 JVM,就可以執行位元組碼檔案,執行我們編寫的 Java 程式。所以這也就是 Java 跨平台性良好,平台無關特性的來歷。
而這個過程中,我們編寫的 Java 程式沒有做任何改變,僅僅是通過 JVM 這一”中間層“,就能在不同平台上執行,真正實現了”一次編譯,到處執行“的目的。
JVM 是一個“橋樑”,是一個“中介軟體”,是實現跨平台的關鍵,Java 程式碼首先被編譯成位元組碼檔案,再由 JVM 將位元組碼檔案翻譯成機器語言,從而達到執行 Java 程式的目的。
注意:編譯的結果不是生成機器碼,而是生成位元組碼,位元組碼不能直接執行,必須通過 JVM 翻譯成機器碼才能執行。不同平台下編譯生成的位元組碼是一樣的,但是由 JVM 翻譯成的機器碼卻不一樣。
所以,執行 Java 程式必須有 JVM 的支援,因為編譯的結果不是機器碼,必須要經過 JVM 的再次翻譯才能執行。即使你將 Java 程式打包成可執行檔案(例如 .exe),仍然需要JVM的支援。
注意:跨平台的是 Java 程式,不是 JVM。JVM 是用 C/C++ 開發的,是編譯後的機器碼,不能跨平台,不同平台下需要安裝不同版本的 JVM。
圖 1 JVM 實現跨平台