1. 程式人生 > >JVM系列第3講:到底什麼是虛擬機器?

JVM系列第3講:到底什麼是虛擬機器?

我們都知道在 Windows 系統上一個軟體包裝包是 exe 字尾的,而這個軟體包在蘋果的 Mac OSX 系統上是無法安裝的。類似地,Mac OSX 系統上軟體安裝包則是 dmg 字尾,同樣無法在 Windows 系統上安裝。

為什麼不同系統上的軟體無法安裝,這是因為作業系統底層的實現是不一樣的。對於 Windows 系統來說,exe 字尾的軟體程式碼最終編譯成 Windows 系統能識別的機器碼。而 Mac OSX 系統來說,dmg 字尾的軟體程式碼最終編譯成 Mac OSX 系統能識別的程式碼。

系統軟體無法通用是一個常見的問題。但使用過 Java 的同學都知道,Java 程式碼可以在服務端(Linux 系統)執行,也可以在 Windows 系統執行,但我們並沒有生成多份不同的程式碼。所以 Java 語言是如何做到的呢?

與其他語言不同,Java 語言並不直接將程式碼編譯成與系統有關的機器碼,而是編譯成一種特定的語言規範,這種語言規範我們稱之為位元組碼。無論 Java 程式要在 Windows 系統,還是 Mac OSX 系統,抑或是 Linux 系統,它首先都得編譯成位元組碼檔案,之後才能執行。

但即使編譯成位元組碼檔案了,各個系統還是無法明白位元組碼檔案的內容,這時候就需要 Java 虛擬機器的幫助了。Java 虛擬機器會解析位元組碼檔案的內容,並將其翻譯為各作業系統能理解的機器碼。

簡單地說,對於同樣一份 Java 原始碼檔案,我們編譯成位元組碼之後,無論是 Linux 系統還是 Windows 系統都不認識。這時候 Java 虛擬機器就是一個翻譯官,在 Linux 系統上翻譯成 Linux 機器碼給 Linux 系統聽,在 Windows 系統上翻譯成 Windows 機器碼給 Windows 系統聽。這樣一來,Java 就實現了「Write Once,Run Anywhere」的偉大願景了。

在 Java 虛擬機器還沒出現之前,為了支援軟體在不同系統上執行,我們必須在多個平臺寫多份程式碼,分別對應特定的系統。但 Java 虛擬機器出現之後,你只需要按照特定規範編譯書寫,編譯器編譯成位元組碼檔案後,虛擬機器會幫你將位元組碼生成對應的 Windows Code 和 Mac Code。本質上最終還是會生成 Windows Code 和 Mac Code 兩份機器程式碼,但對於開發人員來說,卻只需要寫一次程式碼了。Java 虛擬機器幫開發人員承擔了重複的工作,讓開發效率更高了。

很多初學者關於 Java 虛擬機器有一個誤區,他們會覺得 Java 虛擬機器只能執行 Java 程式碼。但實際上 Java 虛擬機器執行的是位元組碼檔案。

換句話說,如果你用 php 語言寫一段程式碼,並自己用特定編譯器能生成符合位元組碼規範的位元組碼檔案,那麼 Java 虛擬機器也是可以執行的。

所以雖然名字是 Java 虛擬機器,但 Java 虛擬機器與 Java 語言沒有直接關係,它只按照 Java 虛擬機器規範去讀取 Class 檔案,並按照規定去解析、執行位元組碼指令,僅此而已。

如果你夠牛逼,你完全可以寫一個編譯器,將 PHP 語言程式碼編譯成符合 Java 虛擬機器規範的位元組碼檔案,那麼 Java 虛擬機器也是可以執行的。

準確地說,Java 虛擬機器與位元組碼檔案(Class檔案)繫結。

最後,讓我們回顧一下,到底什麼是虛擬機器?其實 Java 虛擬機器就是一個位元組碼翻譯器,它將位元組碼檔案翻譯成各個系統對應的機器碼,確保位元組碼檔案能在各個系統正確執行。

參考資料

JVM系列目錄


如果只是看,其實無法真正學會知識的。為了幫助大家更好地學習,我建了一個虛擬機器群,專門討論學習 Java 虛擬機器方面的內容,每週針對我所發文章進行討論答疑。如果你有興趣,關注「Java技術精選」公眾號,通過右下角選單「入群交流」加我好友,小助手會拉你入群。