JRE 和 JDK 的区别:JVM 的作用与 Java 安装包选择
JRE(Java 运行时环境)运行已编译的 Java 程序。JDK(Java 开发工具包)提供运行时功能以及编译器和开发工具,因此在学习 Java 或构建源代码时,应选择 JDK。要运行现有应用,请遵循其运行时要求;打包了自身运行时的应用可能不需要单独安装 Java。
什么是 JRE?
JRE 是运行已编译 Java 程序所需的环境。它结合了 JVM(Java 虚拟机)、标准类库和支持运行时的文件。字节码是 JVM 使用的指令格式,通常存储在由 Java 源代码生成的 .class 文件中。
一个典型的仅运行时的 JRE 包不提供 javac 源代码编译器。因此,能够运行 java 并不证明已安装开发工具。同时要区分运行时环境的概念与特定下载站点上可用的包名称。
什么是 JDK?
JDK 提供用于开发和运行 Java 程序的工具。使用 javac 来编译源文件,使用 java 来运行程序。开发 JDK 已经提供了执行能力,因此仅仅为了使用该 JDK 运行程序,你无需安装第二个 JRE。
javac将.java源文件编译成.class文件。java启动 JVM 并运行 Java 程序。jar将类和资源打包到 JAR(Java 归档)文件中。javadoc从声明和文档注释生成 API(应用程序编程接口)文档。jdb支持调试,包括停止执行和检查变量。
这并不意味着 JDK 包含所有编辑器或集成开发环境(IDE)。你可以单独选择一个编辑器,而 IDE 可能需要你选择一个项目 JDK 来构建代码。编译器的作用在 Oracle 的 javac 参考文档 中有描述。
JVM、JRE 和 JDK 之间有什么关系?
JVM 是执行字节码的组件。JRE 添加了库和支持文件以形成运行时环境;JDK 提供开发工具,同时也提供运行时功能。这些术语描述了不同的角色和范围。
例如,javac 将 HelloWorld.java 转换为 HelloWorld.class,并且 java HelloWorld 在 JVM 上启动程序。类文件可以在具有兼容运行时的其他操作系统上运行,但使用本地库或特定 Java 版本的应用程序有额外要求。有关 JVM 与类文件之间关系的详细信息,请参阅 Java 虚拟机规范介绍 。
JRE 与 JDK 对比
| 标准 | 仅运行时 JRE | JDK |
|---|---|---|
| 主要用途 | 运行已编译的应用程序 | 开发、编译和运行应用程序 |
| JVM 和运行时库 | 已包含 | 已包含 |
| java 启动器 | 通常可用 | 可用 |
| javac 编译器 | 通常缺失 | 可用 |
| 何时选择它 | 应用程序需要兼容的外部运行时 | 学习 Java、构建源代码或开发工作 |
| 下载可用性 | 取决于供应商、版本和操作系统 | 选择供应商和支持的平台 |
此表比较了仅运行时包和开发工具包的一般角色。自定义运行时可能包含不同的模块选择,因此仅凭名称不能保证存在每个库或工具。
现代 JDK 中是否包含 JRE 文件夹?
“JDK 包含 JRE” 是运行时功能的有用简写,但它并不是对每个当前目录布局的准确描述。JDK 8 及更早版本使用了内部 jre/ 目录;JDK 9 引入了模块化运行时映像。Oracle 在 JDK 11 中停止提供单独的 JRE 和 Server JRE 下载。Oracle JDK 11 迁移指南 解释了这些打包和布局的变化。
这并不意味着每个供应商都停止分发仅运行时的软件包。Eclipse Temurin 下载页面 区分了 JDK 和 JRE 软件包;请检查所需版本和操作系统实际可用的内容。某个供应商的打包更改并不是通用的 Java 规则。
开发者还可以使用 JDK 的 jlink 工具将所需模块及其依赖项组合成自定义运行时镜像。将这样的运行时与应用程序捆绑可以减少对单独安装系统 JRE 的需求。其模块选择和更新仍然由分发者负责,如 jlink 参考 中所解释的。
你应该选择哪个软件包和版本?
- 学习和开发: 选择课程或项目所需的 JDK 版本,包括构建工具和库支持的版本。
- 运行现有应用程序: 检查其安装说明中所需的 Java 版本以及是否需要外部运行时。更改系统 Java 可能对已捆绑运行时的应用程序没有影响。
- 服务器部署: 匹配所需的模块、操作系统和 CPU 架构。构建源代码或需要 JDK 工具的服务器可能需要 JDK。
仅仅版本号更大并不保证兼容性。例如,Java 17 运行时不一定能读取为 Java 21 编译的类。在较新的 Java 上运行旧应用程序同样需要检查已删除的功能和库的兼容性。
对于你自己的源代码,在针对早期受支持的 Java 版本时,考虑使用 javac --release。它会限制语言特性、平台 API 和类文件输出,但并不会自动使外部依赖兼容。请在实际的目标运行时上测试结果。
安装 JDK 并检查所选的可执行文件
在官方下载页面上,选择软件包类型、Java 版本、操作系统和 CPU 架构,例如 x64 或 ARM64。如果发布方提供校验和,可在安装前参考使用哈希值验证下载文件的方法检查文件。
Windows 安装和检查
使用 Eclipse Temurin MSI 安装程序时,Custom Setup选择安装目录和功能。将 Java 添加到 PATH 有助于命令行使用;如果你的构建工具需要,请选择 JAVA_HOME 功能。有关这些选项,请参见 Temurin Windows 安装指南。安装完成后,关闭现有终端并打开一个新的终端。
java -version
javac -version
检查两个命令是否都能工作,并显示预期的 Java 主版本。如果只有 java -version 能工作,那么运行时已找到,但编译器可能不可用。在 PowerShell 中,检查所选路径:
Get-Command java,javac | Select-Object Name,Source
PATH 是终端搜索可执行文件的位置列表。JAVA_HOME 指定使用该变量的工具的 JDK 位置;将其指向 JDK 根目录,而不是其 bin 目录。如果这两个设置指向不同的安装位置,终端和构建工具可能使用不同的 Java 版本。
macOS 和 Linux 检查
使用与你的操作系统匹配的安装包或安装程序;请参考 Temurin 平台安装指南 获取实际操作步骤。安装完成后,运行 java -version 和 javac -version。要检查你的 shell 解析到的内容,请使用:
command -v java
command -v javac
结果可能是符号链接或版本管理器位置,因此不要仅从路径推断 Java 版本。还要检查 IDE 的项目 JDK 和构建结果。在移除旧版本安装之前,为每个项目选择新的 JDK,会更容易回到可用配置。
通过小示例理解编译与运行
在有 JDK 的情况下,创建一个空的工作目录,并将此源文件保存为 HelloWorld.java。确保文件名的大小写与类名匹配,并确认编辑器没有添加 .txt 扩展名。示例中未使用包声明或外部库。
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
在包含该文件的目录中打开终端,然后按顺序运行以下命令:
javac HelloWorld.java
java -cp . HelloWorld
第一个命令会创建一个类文件。第二个命令会在当前目录(.)中搜索 HelloWorld 类并运行它。不要在类名后追加 .class。预期输出为:
Hello, Java!
JDK 11及更高版本也可以直接使用java HelloWorld.java启动源文件。这会在内部执行编译,因此启动器的名称并不意味着仅运行时的JRE可以执行相同的操作。两步示例使源代码/类的区别可见。有关源文件执行的条件,请参见java 启动源文件的官方说明。
要将编译后的类打包成可执行JAR,请在创建HelloWorld.class后,在同一目录中运行以下命令:
jar --create --file hello.jar --main-class HelloWorld HelloWorld.class
java -jar hello.jar
创建归档使用的是开发工具;运行这个完成的JAR需要兼容的运行时。其他应用程序可能需要额外的库或启动选项。有关归档创建选项,请参见jar命令参考。
排查常见的安装和启动问题
| 症状 | 检查内容 | 操作步骤 |
|---|---|---|
| 找不到 java 或 javac | 可执行文件存在且 PATH 中包含目标 JDK 的 bin 目录 | 打开一个新的终端;也可使用完整路径检查可执行文件 |
| java 可用,但 javac 不可用 | 仅运行时包或混合可执行路径 | 安装开发版 JDK 或选择现有 JDK 的路径 |
| UnsupportedClassVersionError | 运行时支持的类文件版本 | 使用兼容的运行时;如适用,请为目标版本重建自己的代码 |
| Could not find or load main class(找不到或无法加载主类) | 类名、工作目录和类路径 | 对于此示例,在包含 HelloWorld.class 的目录中运行 java -cp . HelloWorld |
| 在 IDE 中有效,在终端中失败 | 项目 JDK 与终端 java 和 javac | 分别检查 IDE、PATH、JAVA_HOME 和构建工具的 JDK 选择 |
诊断故障时,首先确定实际运行的是哪个可执行文件。确认路径和版本正确且小示例能够运行后,再检查应用程序的依赖关系和启动选项。




