Java 平臺
Java 平臺是 Oracle 提供的計算平臺的名稱,它幫助使用者執行和開發Java 應用程式。該平臺不僅支援使用者執行和開發 Java 應用程式,還提供各種工具來幫助開發人員有效地使用 Java 程式語言。
該平臺由兩個基本軟體組成
- Java 執行時環境 (JRE),用於執行 Java 應用程式和 applet;以及
- Java 開發工具包 (JDK),用於開發這些 Java 應用程式和 applet。如果您安裝了 JDK,您應該知道它也配備了 JRE。因此,對於本書的所有目的,您只需要 JDK。
在本節中,我們將更詳細地探討 Java 平臺的這兩個軟體元件的作用。
Java 執行時環境 (JRE)
[edit | edit source]任何用 Java 程式語言編寫的程式碼都可以執行在任何作業系統、平臺或體系結構上——事實上,它可以在支援 Java 平臺的任何裝置上執行。在 Java 出現之前,要實現這種程度的無處不在是非常困難的。如果為基於 Unix 的系統編寫了一個軟體,則無法在 Windows 系統上執行相同的應用程式——在這種情況下,該應用程式僅適用於基於 Unix 的系統。
Java 程式語言開發中的一個主要里程碑是開發了一個特殊的執行時環境,該環境將執行任何 Java 應用程式,獨立於計算機的作業系統、平臺或體系結構。
Java 執行時環境 (JRE)位於機器的作業系統、平臺和體系結構之上。如果並且當執行 Java 應用程式時,JRE 充當底層平臺和該應用程式之間的聯絡人。它解釋 Java 應用程式以根據底層平臺執行,這樣在執行應用程式時,它看起來和執行起來就像一個本地應用程式。完成這種複雜的聯絡協議的 JRE 部分稱為Java 虛擬機器 (JVM)。
圖 1:Java 應用程式可以一次編寫,然後隨處執行。Java 平臺的這個功能
在正式的 Java 文字中通常縮寫為WORA。 |
執行原生 Java 程式碼(或位元組碼)
[edit | edit source]原生 Java 應用程式以一種稱為位元組碼的特殊格式儲存。位元組碼保持不變,無論它執行在何種硬體體系結構、作業系統或軟體平臺上。在檔案系統上,Java 位元組碼駐留在具有.class(也稱為類檔案)或.jar(也稱為Java 存檔)副檔名的檔案中。為了執行位元組碼,JRE 附帶了一個特殊的工具(恰如其分地命名為java)。
假設您的位元組碼稱為SomeApplication.class。如果您想執行此 Java 位元組碼,您需要在命令提示符(在 Windows 上)或終端(在 Linux 或 Mac OS 上)中使用以下命令
執行
$ java SomeApplication |
如果您想執行一個具有.jar副檔名的 Java 位元組碼(例如,SomeApplication.jar),您需要在命令提示符(在 Windows 上)或終端(在 Linux 或 Mac OS 上)中使用以下命令
使用 jar 執行
$ java -jar SomeApplication.jar |
| 並非所有 Java 類檔案或 Java 存檔都是可執行的。因此,java工具只能執行可執行檔案。不可執行的類檔案和 Java 存檔簡稱為類庫。 |
您有 JRE 嗎?
[edit | edit source]大多數計算機都預裝了 JRE。如果您的計算機沒有 JRE,那麼上面的命令將無法工作。您可以隨時透過在命令提示符(在 Windows 上)或終端(在 Linux 或 Mac OS 上)中編寫以下命令來檢查計算機上安裝的 JRE 版本
Java 版本
$ java -version |
Java 虛擬機器 (JVM)
[edit | edit source]JRE 中最重要的是Java 虛擬機器 (JVM)。JVM 就像一個虛擬處理器,使 Java 應用程式能夠在本地系統上執行。它的主要目的是解釋(讀取翻譯)接收到的位元組碼,使其看起來像原生代碼。舊的 Java 架構使用解釋過程來執行 Java 位元組碼。即使解釋過程將 WORA 原理帶到了不同的機器,它也存在一個缺點——它消耗了大量時間,並密集地佔用系統處理器來載入應用程式。
圖 2:JVM 直譯器翻譯位元組碼逐行,使其看起來像正在執行本地應用程式。
|
即時編譯
[edit | edit source]從 1.2 版開始,JRE 提供了更強大的 JVM。它不再解釋位元組碼,而是直接將程式碼直接轉換為本地系統上的等效原生代碼。這種轉換過程稱為即時編譯或JIT 編譯。此過程僅在第一次執行位元組碼時發生。除非位元組碼本身發生變化,否則 JVM 在每次後續執行時都會使用位元組碼的編譯版本。這樣做節省了大量時間和處理器工作量,使應用程式能夠以更快的速度執行,但以第一次執行時會有很小的延遲為代價。
圖 3:即時編譯器只在第一次執行時將位元組碼編譯為等效的原生代碼。在每次後續
執行時,JVM 只使用已經編譯的原生代碼來最佳化效能。 |
本地最佳化
[edit | edit source]JVM 是一個智慧的 _虛擬_ 處理器。它能夠識別 Java 程式碼本身中可以進行最佳化以實現更快、更好效能的區域。根據您 Java 應用程式的每次後續執行,JVM 將對其進行最佳化以使其執行得更好。
| Java 程式碼中有一些部分不需要在執行時進行 JIT 編譯,例如 反射 API;因此,使用此類函式的程式碼不一定會完全編譯為本機程式碼。 |
Java 不是第一個基於虛擬機器的平臺,儘管它迄今為止是最成功和最著名的平臺。之前使用虛擬機器技術主要涉及 模擬器 來幫助開發尚未開發的硬體或作業系統,但 JVM 被設計為完全用軟體實現,同時使其易於有效地將實現移植到各種硬體。
JRE 負責在多個平臺上執行 Java 程式碼,但是作為開發人員,我們對用 Java 編寫純程式碼感興趣,然後可以將其轉換為 Java 位元組碼以進行大規模部署。作為開發人員,我們 _不需要_ 編寫 Java 位元組碼;而是用 Java 程式語言編寫程式碼(這與編寫 C 或 C++ 程式碼非常相似)。
下載 JDK 後,開發人員可以確保他們的系統擁有適當的 JRE 和其他工具來幫助開發 Java 程式語言中的應用程式。Java 程式碼可以在副檔名為 .java 的檔案中找到。這些檔案稱為 _**Java 原始檔**_。為了將這些原始檔中的 Java 程式碼轉換為 Java 位元組碼,您需要使用 JDK 安裝的 **Java 編譯器** 工具。
**Java 編譯器** 工具(在 JDK 中名為 javac)是 JDK 中最重要的實用程式。為了將 Java 原始檔(例如,SomeApplication.java)編譯為其相應的 Java 位元組碼,您需要在命令提示符(在 Windows 上)或終端(在 Linux 或 Mac OS 上)中使用以下命令
編譯
javac SomeApplication.java |
此命令將 SomeApplication.java 原始檔轉換為其等效的 Java 位元組碼。生成的位元組碼將存在於一個名為 SomeApplication.class 的新建立檔案中。將 Java 原始檔轉換為其等效位元組碼的過程稱為 _**編譯**_。
**圖 4:**基本的 Java 編譯過程
|
JDK 中提供大量工具,這些工具將在您學習本書的過程中逐步解釋。這些工具按其使用順序簡要列出如下
appletviewer— Java 小程式需要特定的環境才能執行。通常,此環境由具有 Java 外掛的瀏覽器和提供小程式的 Web 伺服器提供。但是,在開發和測試小程式期間,可能更方便地啟動小程式,而無需使用瀏覽器和 Web 伺服器。在這種情況下,可以使用 Oracle 的 JDK 中的 appletviewer 來執行小程式。
- 有關注釋處理的更多資訊,請 閱讀此內容
在 Java 1.5(別名 Java 5.0)中,Oracle 添加了一種稱為 _註釋_ 的機制。註釋允許在 Java 原始碼中新增元資料,甚至提供機制將這些元資料傳遞到已編譯的 .class 檔案中。
apt— 一種註釋處理工具,它會深入到原始碼中,找到原始碼中的註釋語句,並在找到已知註釋時執行操作。最常見的任務是生成一些特定的原始碼。當在原始碼中找到註釋時,apt 執行的操作不是硬編碼到 apt 中的。相反,必須用 Java 編寫特定的註釋處理程式。這些處理程式稱為註釋處理器。它也可以用一種簡單的方式描述,而不使用 Oracle 的術語:apt 可以被視為一種原始碼預處理器框架,而註釋處理器通常是程式碼生成器。
javah— Java 類可以呼叫已準備好從 Java 呼叫的本機或非 Java 程式碼。JNI(Java 本機介面)中指定了詳細資訊和過程。通常,本機程式碼是用 C(或 C++)編寫的。JDK 工具 javah 透過生成 C 標頭檔案和 C 存根程式碼來幫助編寫必要的 C 程式碼。
extcheck— 它可以在將 Java 擴充套件安裝到 JDK 或 JRE 環境之前使用。它檢查特定 Jar 檔案是否與已安裝的擴充套件衝突。該工具首先出現在 Java 1.5 中。
JDK 附帶大量與 Java 安全功能相關的工具。使用這些工具首先需要研究特定的安全機制。這些工具是
keytool— 用於管理金鑰和證書jarsigner— 用於生成和驗證 JAR(Java 檔案)的數字簽名policytool— 用於編輯策略檔案kinit— 用於獲取 Kerberos v5 票證klist— 用於管理 Kerberos 憑據快取和金鑰表ktab— 用於管理金鑰表中的條目
jar—(代表 Java 歸檔器)是一個用於建立 Java 檔案或 jar 檔案的工具,副檔名為.jar。Java 檔案是已編譯的 Java 類和這些類可能在執行時需要的其他資源(例如文字檔案、配置檔案、影像)的集合。從內部來說,jar 檔案實際上是一個 .zip 檔案。
jdb—(代表 Java 偵錯程式)是一個命令列控制檯,它為 Java 程式提供了 除錯 環境。儘管您可以使用此命令列控制檯,但 IDE 通常提供更易於使用的除錯環境。
隨著程式變得越來越大、越來越複雜,程式設計師需要方法來跟蹤更改,以便在程式碼演變的每個階段更好地理解程式碼。幾十年來,程式設計師一直在使用稱為註釋的特殊程式設計結構,這些結構是幫助在原始碼中宣告程式碼片段的使用者定義的區域。但註釋很容易變得冗長且難以理解,更不用說在具有數百行程式碼的應用程式中難以閱讀了。
javadoc— Java 為使用者提供了一種使用特殊註釋系統和 javadoc 工具輕鬆釋出有關程式碼的文件的方法。javadoc 工具會生成有關一組使用者建立的 Java 類的應用程式程式設計介面 (API) 的文件。javadoc 會從.java原始檔中讀取原始檔註釋,並生成更易於閱讀和理解的 HTML 文件,而無需檢視程式碼本身。
javap— 當 Javadoc 提供對 Java 類 API 和文件的詳細檢視時,javap 工具會列印有關類中成員(建構函式、方法和變數)的資訊。換句話說,它列出了類的 API 和/或類的已編譯指令。javap 是 Java 位元組碼的格式化反彙編器。
native2ascii 是一種重要的工具,雖然不太為人所知,但它在編寫屬性檔案(包含配置資料的檔案)或資源包(包含文字語言翻譯的檔案)時至關重要。
此類檔案只能包含 ASCII 和 Latin-1 字元,但國際程式設計師需要完整的字元集。只有將非 ASCII 和非 Latin-^1 字元轉換為 Unicode 轉義序列(\uXXXX 符號),這些字元才能出現在屬性檔案和資源包中。
native2ascii 負責編寫這些轉義序列。您可以在編輯器中使用適當的字元編碼編寫國際文字,然後使用 native2ascii 生成包含嵌入式 Unicode 轉義序列的必要 ASCII 文字。儘管名稱如此,native2ascii 也可以從 ASCII 轉換為本機,因此它可用於將現有的屬性檔案或資源包轉換回其他編碼。
native2ascii 最適合整合到構建系統中以自動化轉換。
遠端方法呼叫 (RMI) 工具
[edit | edit source]
Java IDL 和 RMI-IIOP 工具
[edit | edit source]
部署與 Web 啟動工具
[edit | edit source]
瀏覽器外掛工具
[edit | edit source]
監控與管理工具 / 故障排除工具
[edit | edit source]在 Java 1.5 中,除了故障排除工具之外,還為 JDK 添加了一組監控和管理工具。
監控和管理工具旨在監控和管理虛擬機器以及執行環境。例如,它們允許監控 Java 程式執行期間的記憶體使用情況。
故障排除工具提供了對虛擬機器各個方面的相當深奧的見解。(有趣的是,Java 偵錯程式並未歸類為故障排除工具。)
目前,所有監控與管理以及故障排除工具都被標記為“實驗性”(這不會影響 jdb)。因此,它們可能會在未來的 JDK 中消失。
Java 類庫 (JCL)
[edit | edit source]在大多數現代作業系統中,會提供大量可重用程式碼以簡化程式設計師的工作。這些程式碼通常以一組 可動態載入的庫的形式提供,應用程式可以在執行時呼叫這些庫。由於 Java 平臺不依賴於任何特定的作業系統,因此應用程式無法依賴任何現有的庫。相反,Java 平臺提供了一套完整的標準類庫,其中包含在現代作業系統中常見的許多相同可重用功能。
Java 類庫在 Java 平臺中起著三個作用。與其他標準程式碼庫一樣,它們為程式設計師提供了一套眾所周知的函式來執行常見任務,例如維護專案列表或執行復雜的字串解析。此外,類庫為通常高度依賴硬體和作業系統的任務提供了抽象介面。網路訪問和檔案訪問等任務通常高度依賴於平臺的本機功能。Java java.net 和 java.io 庫在內部實現了所需的本機程式碼,然後為 Java 應用程式提供了一個標準介面來執行這些任務。最後,某些底層平臺可能不支援 Java 應用程式期望的所有功能。在這些情況下,類庫可以使用可用的任何功能來模擬這些功能,或者提供一種一致的方法來檢查特定功能是否存在。
類似概念
[edit | edit source]Java 平臺和“一次編寫,隨處執行”原則的成功導致了類似框架和平臺的開發。其中最值得注意的是微軟的 .NET 框架 及其開源等效物 Mono.
.NET 框架
[edit | edit source].NET 框架借鑑了 Java 的許多概念和創新——它們的 JVM 替代方案被稱為 通用語言執行時 (CLR),而它們的位元組碼替代方案被稱為 通用中間語言 (CIL)。實際上,.NET 平臺有 Java 類語言的實現,稱為 Visual J#(以前稱為 J++)。
J# 通常不受 JVM 支援,因為 .NET 平臺不會將 J# 編譯為 Java 位元組碼,而是將其編譯為 CIL,因此 J# 與 Java 程式語言有所不同。此外,由於 J# 實施了 .NET 基本類庫 (BCL) 而不是 Java 類庫,因此 J# 僅僅是 Java 程式語言的非標準擴充套件。由於開發人員缺乏興趣,微軟不得不停止對 J# 的支援,並專注於類似的程式語言:C#。
面向 JVM 的第三方編譯器
[edit | edit source]通常情況下,Java 本身是指為 Java 平臺設計的 Java 程式語言。程式語言通常不在“平臺”短語的範圍內。但是,Oracle 不鼓勵使用其他任何語言與平臺一起使用,並將 Java 程式語言列為 Java 2 平臺的核心部分。因此,語言和執行時通常被認為是一個整體。
在某些情況下,您可能希望使用其他語言(例如,Python)進行程式設計,但仍能生成 Java 位元組碼(而不是 Python 編譯程式碼)以與 JVM 一起執行。許多第三方程式語言供應商提供可以將用其語言編寫的程式碼編譯為 Java 位元組碼的編譯器。例如,Python 開發人員可以使用 Jython 編譯器將 Python 程式碼編譯為 Java 位元組碼格式(如下所示)。
圖 5:面向 JVM 的第三方編譯,用於將非 Java 原始碼編譯為 Java 位元組碼。圖示示例
顯示 Python 原始碼被編譯為 Python 編譯程式碼和 Java 位元組碼。 |
最近,面向 JVM 的第三方程式設計和指令碼語言發展迅速。其中一些語言也用於擴充套件 Java 語言本身的功能。以下是一些示例





