其實很多 Java 程序員在寫了很多代碼后,你問他 jre 和 jdk 之間有什么關(guān)系,jvm 又是什么東西,很多人不知所云。本篇不會講述 jvm 底層是如何與不同的系統(tǒng)進行交互的,而主要理清楚三者之間的區(qū)別,搞清楚我們寫的 xxx.java 文件是被誰編譯,又被誰執(zhí)行,為什么能夠跨平臺運行。
首先,我們分別對這三者進行闡述。
JVM :英文名稱(Java Virtual Machine),就是我們耳熟能詳?shù)?Java 虛擬機。它只認識 xxx.class 這種類型的文件,它能夠?qū)?class 文件中的字節(jié)碼指令進行識別并調(diào)用操作系統(tǒng)向上的 API 完成動作。所以說,jvm 是 Java 能夠跨平臺的核心,具體的下文會詳細說明。
JRE :英文名稱(Java Runtime Environment),我們叫它:Java 運行時環(huán)境。它主要包含兩個部分,jvm 的標準實現(xiàn)和 Java 的一些基本類庫。它相對于 jvm 來說,多出來的是一部分的 Java 類庫。
JDK :英文名稱(Java Development Kit),Java 開發(fā)工具包。jdk 是整個 Java 開發(fā)的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。
顯然,這三者的關(guān)系是:一層層的嵌套關(guān)系。JDK>JRE>JVM。
接著,提出一個問題:為什么我們的電腦在裝完 jdk 后會有兩個版本的 jre?
留心的同學可能會發(fā)現(xiàn),我們的 jdk 安裝成功后,在 C:\Program Files\Java 目錄會是這樣的(這里,我是裝的 jdk1.8 的版本)
而 jdk 的子目錄下也存在一個 jre。
這兩個不同版本的 jre 相互之間有什么聯(lián)系嗎?
答案是:沒有聯(lián)系。甚至準確的來說,它倆是一樣的,無論是用哪一個都是可以的。只是很多人習慣將會單獨安裝另一個 jre,雖然單獨安裝的 jre 也并沒有被使用,原因可能就是剛開始大家都不清楚 jdk 和 jre 之間的關(guān)系,所以就默認的都安裝上了。
在 jdk 的 bin 目錄下,基本上都是一些可執(zhí)行文件,并且它們還不大。其實這些可執(zhí)行文件只是外層的一層封裝而已,這樣的目的是避免輸入的命令過長。例如 javac.exe 內(nèi)部調(diào)用的其實是 JDK 中 lib 目錄中的 tools.jar 中 com.sun.tools.javac.Main 類,也就是說這些工具只是入口而已。而實際上它們本身又都是由 Java 編寫的,所以在 jdk 目錄下的 jre 既提供了這些工具的運行時環(huán)境,也提供了我們編寫完成的 Java 程序的運行時環(huán)境。
所以,很明顯,jdk 是我們的開發(fā)工具包,它集成了 jre ,因此我們在安裝 jdk 的時候可以選擇不再安裝 jre 而直接使用 jdk 中的 jre 運行我們的 Java 程序。(但是大部分人都默認將兩個都裝上了)。但是如果你的電腦不是用來開發(fā) Java 程序的,而僅僅是用來部署和運行 Java 程序的,那么完全可以不用安裝 jdk,只需要安裝 jre 即可。
下一個問題,Java 為什么能跨平臺,實現(xiàn)一次編寫,多處運行?
Java 能夠跨平臺運行的核心在于 JVM 。不是 Java 能夠跨平臺,而是它的 jvm 能夠跨平臺。我們知道,不同的操作系統(tǒng)向上的 API 肯定是不同的,那么如果我們想要寫一段代碼調(diào)用系統(tǒng)的聲音設(shè)備,就需要針對不同系統(tǒng)的 API 寫出不同的代碼來完成動作。
而 Java 引入了字節(jié)碼的概念,jvm 只能認識字節(jié)碼,并將它們解釋到系統(tǒng)的 API 調(diào)用。針對不同的系統(tǒng)有不同的 jvm 實現(xiàn),有 Linux 版本的 jvm 實現(xiàn),也有 Windows 版本的 jvm 實現(xiàn),但是同一段代碼在編譯后的字節(jié)碼是一樣的。引用上面的例子,在 Java API 層面,我們調(diào)用系統(tǒng)聲音設(shè)備的代碼是唯一的,和系統(tǒng)無關(guān),編譯生成的字節(jié)碼也是唯一的。但是同一段字節(jié)碼,在不同的 jvm 實現(xiàn)上會映射到不同系統(tǒng)的 API 調(diào)用,從而實現(xiàn)代碼的不加修改即可跨平臺運行。
本篇文章主要描述了 Java 相關(guān)的最基本的概念,理解了這幾個基本的概念后,后續(xù)的學習才會有根有據(jù),不會稀里糊涂的。
文章中的所有代碼、圖片、文件都云存儲在我的 GitHub 上:
(https://github.com/SingleYam/overview_java)
歡迎關(guān)注微信公眾號:撲在代碼上的高爾基,所有文章都將同步在公眾號上。