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 语言本身的功能。以下是一些示例