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





