前言
在面試中,被問到了一個問題:java
Windows中的JDK和Linux中的JDK是否相同?面試
其實,以上這個問題是一個子問題。本來的問題是:如何理解Java的跨平臺機制。因爲原問題顯得有些寬泛,所以延伸出一個子問題,在本篇博客中爭取可以完整地回答。
本文力求創建起本身知識體系中Java的基石,但願在閱讀本文以後,同時能夠很好地回答上述的跨平臺機制這個基礎問題。架構
1、JDK的架構
下面這張是從Oracle官方文檔中找到的JDK架構圖,很是細緻的展示了JDK每一個層級的架構和組件。如下將會挑選重點,談談本身的理解。工具
JDK
首先咱們來看JDK的組成,總的來講,JDK包括兩部分:優化
- 第一部分是Tools & Tool APIs,這包括了將java文件編譯成爲class文件的工具,好比javac,java,還有調試java程序的各類工具;
- 第二部分是JRE,JRE是Java的運行時環境,被編譯後的java程序,就是在JRE中獲得執行。
因爲本文只想要分析JDK、JRE等比較宏觀的相關概念,因此能夠將上面的複雜的JDK架構圖簡化,獲得下面一張簡圖。 從中能夠很好的看到JDK、JRE和JVM的架構關係。spa
JRE
JRE是Java的運行時環境,總的來看,包括三部份內容:操作系統
- 首先是java的class文件或者是java的package,這些class文件和package有時須要和被編譯後的java程序一塊兒,獲得執行;
- 第二是java運行時的庫文件,例如rt.jar,有了庫文件的支持,被編譯後的java文件才能獲得正確的執行;
- 第三是JVM。JVM是Java虛擬機,是真正執行Java程序的地方。它使用了第一部分的java的class和第二部分的庫文件來實際運行Java程序。不一樣的操做系統或者平臺中,JVM是不一樣的。
看到這裏,相信已經能夠回答文章開頭提出的問題了。Windows中的JDK和Linux中的JDK是否相同?回答是,不相同的!調試
JVM
JVM是Java虛擬機,是Java程序真正獲得執行的地方。不一樣的操做系統或者平臺中,JVM是不一樣的。這也就是爲何Oracle的官網上提供了不一樣平臺的JDK給用戶下載。code
2、Java程序的編譯和執行
下面從JDK,JRE等角度,來簡略的描述Java程序編譯和執行的流程。流程圖以下所示:blog
- Java源代碼,也就是java文件,首先會被JDK編譯,具體來講,是被JDK中的Java Compiler編譯了,而後就會生成Java字節碼(Java Bytecode),這個Bytecode,就是class文件。
- Bytecode會被傳輸到JVM中,JVM會使用JRE中的java class和庫文件與Bytecode一塊兒編譯執行。
- 所謂的編譯執行,其實質上仍是編譯的過程,也就是說,JVM接收的輸入是Java Bytecode,處理後的輸出是基於特定平臺和操做系統的機器碼,這裏說的機器碼,也能夠被認爲是一組指令集。
- 能夠看到在JVM中,有一個橙色的框,是JVM中包含的JIT Complier。JIT Compiler的做用是,對Java Bytecode中的部分字節碼進行優化,這樣能夠生成更高效的機器碼,被底層的物理硬件執行。
總結
寫到這裏,能夠對「Windows中的JDK和Linux中的JDK是否相同」,或者「如何理解Java的跨平臺特性」,進行回答。
- Java平臺的跨平臺特性,從最基礎的角度來講,是由於JVM。不一樣操做系統或者平臺上的JVM是不一樣的,由於JVM要把Java字節碼編譯成爲機器碼,機器碼纔是真正物理硬件執行的指令集。因爲不一樣操做系統或者平臺的硬件架構不一樣,因此必須製做不一樣的JVM,安裝在不一樣的操做系統或者平臺上。
- 看到一位網友的總結,以爲很好:正是由於JVM的不跨平臺特性,才實現了Java語言的跨平臺特性。
- Java的概念中,有「一次編寫,處處運行」,即「Write Once, Run Anywhere」。真正跨平臺的,是Java字節碼,簡單理解就是編譯後的class文件。
- 例如,在Windows上,我javac了一個最簡單的HelloWorld的Java程序,生成了HelloWorld.class,而後我能夠java HelloWorld來執行它。此時,我把HelloWorld.class拷貝到Linux環境中,一樣java HelloWorld來執行,能夠獲得與Windows中相同的結果。事實上,若是我拷貝HelloWorld.java文件到Linux環境中,一樣javac,生成的class文件也是相同的。
- 爲了在不一樣的操做系統中把相同的java程序編譯成爲相同的Java字節碼,jdk中bin目錄下的編譯工具是不相同的,例如javac工具和java工具;由於要將Java字節碼編譯成爲特定平臺上的機器碼,因此JVM所依賴的JRE中的庫文件也是不一樣的,例如rt.jar。
- 因此,Windows中的JDK和Linux中的JDK是徹底不一樣的,相同的是能夠在二者之間通用的Java字節碼。
創做時間:10/11/2016 4:30:18 PM