[JAVA基礎系列]java程式的執行機制分析
阿新 • • 發佈:2019-01-13
我們可以通過helloworld來理解這幾個縮寫詞的具體含義:
public class HelloWorld { public static void main(String[] args) { System.out.println("helloworld"); }}
編譯之後, 我們得到了HelloWorld.class(圖中的"Your program's class files")
在HelloWorld裡面, 我們呼叫了 JAVA API中的 java.lang.System這個類的靜態成員物件 out, out 的靜態方法: public static void println(String string);
然後我們讓虛擬機器器來執行這個HelloWorld。
1. 虛擬機器會在classpath中找到HelloWorld.class。
2. 虛擬機器中的直譯器(interpret)會把HelloWorld.class解釋成位元組碼。
3. 把解釋後的位元組碼交由execution engin執行。
4. execution engin會呼叫native method(即平臺相關的位元組碼)來在host system的stdout(顯示器)的指定部分打印出指定的字串。
5. 這樣, 我們就看到"helloworld"字樣了。
有了這個流程後, 我們就好理解上面幾個術語了:
a. JDK: java develop kit (JAVA API包)
b. SDK: software develop kit, 以前JDK 叫做java software develop kit, 後來出了1.2版本後, 就改名叫jdk了, 省時省力, 節約成本。
c. JRE. java runtime environment 我們的helloworld必須在JRE(JAVA執行環境,JAVA執行環境又叫JAVA平臺)裡面, 才能跑起來。 所以, 顯然地, JRE其實就是JDK + JVM
d. JVM java virtual machine. 簡單地講, 就是把class檔案變成位元組碼, 然後送到excution engin中執行。而為什麼叫虛擬機器, 而不叫真實機呢? 因為JVM本身是又不能運算, 又不能讓顯示器顯示"helloworld"的, 它只能再呼叫host system的API, 比如在w32裡面就會調c++的API, 來讓CPU幫他做做算術運算,來呼叫c++裡面的API來控制顯示器顯示顯示字串。 而這些API不是JDK裡面有的,我們平時又看不見的,所以我們就叫它native api了(亦曰私房XX)。
e. 解釋平臺無關。 有人會說, 在linux的裡面呼叫native api與w32裡面呼叫的api肯定不一樣吧? 那為什麼說JAVA是平臺無關的呢?
其實是這樣的, 君不見java.sun.com裡面又有jdk-for-w32又有jdk-for-linux下載嗎? 剛才不是說了嗎? native api, native api, 就是我們平時看不見的api嗎! 呼叫native這些煩瑣的活兒都讓jdk去做了。所以我們呼叫的時候只用知道jdk(java api) 裡面的java.io.*能提供磁碟訪問功能, java.awt.* 能畫個框框畫個圓圓就行了嗎。 至於JDK又是怎麼呼叫的, 在LINXU上更圓呢? 還是在W32上更圓,(x) 這個就是JDK個人的事情了。(理論上講是一樣圓的, 當然這又和顯示器是否純平相關了:D)
同時, 這裡就引申出了另一個話題。既如何編寫平臺無關的JAVA程式。 其中關鍵的一條, 就是呼叫且只調用jdk中的API, 而不要私自呼叫native api。 原因很簡單啊, JDK-for-linux和JDK-for-w32表面都是一樣的,所以我在w32裡面呼叫JDK寫的java程式,在linux裡面也會一樣的寫法啊, 所以就可以移植來移植去都沒問題。(b) 但是如果我在w32裡面呼叫了 一個圖形顯示的native api, 當我移植到linux去的時候, 誰又能保證裡面也有相同名稱,相同引數,相同返回值, 相同功能的native api供我呼叫呢
public class HelloWorld { public static void main(String[] args) { System.out.println("helloworld"); }}
編譯之後, 我們得到了HelloWorld.class(圖中的"Your program's class files")
在HelloWorld裡面, 我們呼叫了 JAVA API中的 java.lang.System這個類的靜態成員物件 out, out 的靜態方法: public static void println(String string);
然後我們讓虛擬機器器來執行這個HelloWorld。
1. 虛擬機器會在classpath中找到HelloWorld.class。
2. 虛擬機器中的直譯器(interpret)會把HelloWorld.class解釋成位元組碼。
3. 把解釋後的位元組碼交由execution engin執行。
4. execution engin會呼叫native method(即平臺相關的位元組碼)來在host system的stdout(顯示器)的指定部分打印出指定的字串。
5. 這樣, 我們就看到"helloworld"字樣了。
有了這個流程後, 我們就好理解上面幾個術語了:
a. JDK: java develop kit (JAVA API包)
b. SDK: software develop kit, 以前JDK 叫做java software develop kit, 後來出了1.2版本後, 就改名叫jdk了, 省時省力, 節約成本。
c. JRE. java runtime environment 我們的helloworld必須在JRE(JAVA執行環境,JAVA執行環境又叫JAVA平臺)裡面, 才能跑起來。 所以, 顯然地, JRE其實就是JDK + JVM
d. JVM java virtual machine. 簡單地講, 就是把class檔案變成位元組碼, 然後送到excution engin中執行。而為什麼叫虛擬機器, 而不叫真實機呢? 因為JVM本身是又不能運算, 又不能讓顯示器顯示"helloworld"的, 它只能再呼叫host system的API, 比如在w32裡面就會調c++的API, 來讓CPU幫他做做算術運算,來呼叫c++裡面的API來控制顯示器顯示顯示字串。 而這些API不是JDK裡面有的,我們平時又看不見的,所以我們就叫它native api了(亦曰私房XX)。
e. 解釋平臺無關。 有人會說, 在linux的裡面呼叫native api與w32裡面呼叫的api肯定不一樣吧? 那為什麼說JAVA是平臺無關的呢?
其實是這樣的, 君不見java.sun.com裡面又有jdk-for-w32又有jdk-for-linux下載嗎? 剛才不是說了嗎? native api, native api, 就是我們平時看不見的api嗎! 呼叫native這些煩瑣的活兒都讓jdk去做了。所以我們呼叫的時候只用知道jdk(java api) 裡面的java.io.*能提供磁碟訪問功能, java.awt.* 能畫個框框畫個圓圓就行了嗎。 至於JDK又是怎麼呼叫的, 在LINXU上更圓呢? 還是在W32上更圓,(x) 這個就是JDK個人的事情了。(理論上講是一樣圓的, 當然這又和顯示器是否純平相關了:D)
同時, 這裡就引申出了另一個話題。既如何編寫平臺無關的JAVA程式。 其中關鍵的一條, 就是呼叫且只調用jdk中的API, 而不要私自呼叫native api。 原因很簡單啊, JDK-for-linux和JDK-for-w32表面都是一樣的,所以我在w32裡面呼叫JDK寫的java程式,在linux裡面也會一樣的寫法啊, 所以就可以移植來移植去都沒問題。(b) 但是如果我在w32裡面呼叫了 一個圖形顯示的native api, 當我移植到linux去的時候, 誰又能保證裡面也有相同名稱,相同引數,相同返回值, 相同功能的native api供我呼叫呢