Java語言與平臺的區別

李鬆峰發表於2013-05-16

本文摘自《Java程式設計師修煉之》1.1節。

使用Java之前,我們要先弄清楚Java語言和Java平臺之間的區別。然而,有時候不同的作者對語言和平臺的構成會有不同的定義,所以人們有時不太清楚兩者之間的區別,分不清是語言還是平臺提供了程式碼使用的程式設計特性。

因為本書的大部分內容都需要你理解兩者的區別,所以這裡需要說明一下。以下是我們給出的定義。

  • Java語言 在“關於本書”中,我們提到Java語言是靜態型別、物件導向的語言,希望你對這種說法已經非常熟悉了。Java語言還有一個非常明顯的特點,它是(或者說應該是)人類可讀的。
  • Java平臺 平臺是提供執行時環境的軟體。Java虛擬機器(JVM)負責把類檔案形式(人類不可讀)的程式碼連結起來並執行。JVM不能直接解釋Java語言的原始檔,你要先把原始檔轉換成類檔案。

Java作為軟體系統之所以能成功,主要因為它是一種標準。也就是說,它有規範檔案描述它應該如何工作。不同的廠商或專案組可以據此推出自己的實現,這些不同實現的工作方式在理論上是相同的。規範雖然不能保證這些實現處理同一任務時表現如何,但可以保證處理結果的正確性。

控制Java系統的規範有多種,其中最重要的是《Java語言規範》(JLS)和《JVM規範》(VMSpec)。在Java 7中,這兩者之間的界限愈發清晰。實際上,VMSpec不再引用JLS中的任何內容,如果你認為這是Java 7重視Java之外其他語言的訊號,說明你有見微知著的能力!希望你能繼續關注,接下來我們會更加深入地探討這兩個規範之間的差別。

提到Java的雙重角色,你自然想問:“它們兩者之間還有什麼關聯嗎?”如果它們在Java 7中如此涇渭分明,又是如何共同形成我們所熟悉的Java系統的呢?

連線Java語言和平臺之間的紐帶是統一的類檔案(即.class檔案)格式定義。認真研究類檔案的定義能讓你獲益匪淺,這是優秀Java程式設計師向偉大Java程式設計師轉變的一個途徑。圖1-1展示了產生和使用Java程式碼的整個過程。

圖1.1 Java 原始檔被轉換成 .class 檔案,在JIT編譯前載入處理

圖1-1 Java原始碼被轉換成 .class 檔案,在JIT編譯前被載入處理

圖中文字 Class loader:類載入器;Transformed .class:轉換後的.class;Executing code:可執行程式碼;Interpreter:直譯器;JIT compiler:JIT編譯器;Machine code:機器碼

如圖所示,Java程式碼的演進過程從我們可以看懂的Java原始碼開始,然後由javac編譯成.class檔案,變成可以載入到JVM中的形式。值得注意的是,類檔案在載入過程中通常都會被處理和修改。大多數流行框架(特別是打著“企業級”旗號的)都會在類載入過程中對類進行改造。

Java是編譯型語言還是解釋型語言?

大多數開發人員都知道,Java原始檔需要編譯成.class檔案才能在JVM中執行。如果繼續追問,許多開發人員還會告訴你說.class中的位元組碼首先會被JVM解釋,但在稍後即時(JIT)編譯。然而很多人將位元組碼含糊地理解為“在某種虛構的或簡化的CPU上執行的機器碼”。

實際上,JVM位元組碼更像是中途的驛站,是一種從人類可讀的原始碼向機器碼過渡的中間狀態。用編譯原理術語講,位元組碼實際上是一種中間語言(IL)形態,不是真正的機器碼。也就是說,將Java原始碼變成位元組碼的過程不是C或C++程式設計師所理解的那種編譯。Java所謂的編譯器javac也不同於gcc,實際上它只是一個針對java原始碼生成類檔案的工具。Java體系中真正的編譯器是JIT,如圖1-1所示。

有人說Java是“動態編譯”的,他們所說的編譯是指JIT的執行時編譯,不是指構建時建立類檔案的過程。

所以如果被問及“Java是編譯型語言還是解釋型語言”,你可以回答“都是”。

希望我們已經把Java語言和Java平臺之間的區別解釋清楚了。接下來我們進入下一話題,看看Java 7中一些語法上的調整;先從Coin專案中的那些小變化開始。

相關文章