JDK 包含 JRE,现代开发直接装 JDK 即可;Oracle 自 JDK 9 起停供独立 JRE,主流 OpenJDK 发行版亦不再提供;JDK 自带运行时,容器和部署普遍用 JDK 镜像;项目运行实际只需 JVM 与标准类库,但新语法或工具依赖对应 JDK 版本。

JDK 和 JRE 不是“选一个装就行”的关系,而是“开发用 JDK,运行用 JRE(或 JDK 自带的 JRE)”——但现代实践中,绝大多数情况直接装 JDK 就够了,不用单独配 JRE。
为什么现在很少单独安装 JRE
JRE 是 Java Runtime Environment,只包含 java 命令和运行字节码所需的类库、JVM;JDK 是 Java Development Kit,包含 JRE + 编译器 javac、调试器 jdb、打包工具 jar 等开发组件。
- Oracle 自 JDK 9 起不再提供独立 JRE 下载,JRE 被移除
- OpenJDK 各主流发行版(如 Temurin、Zulu、Amazon Corretto)也默认不发布单独 JRE 包
- JDK 安装后自带
jre/目录(JDK 8)或通过--jre子命令导出运行时(JDK 14+),实际运行时仍用同一套 JVM - 容器部署(如 Docker)通常直接用
eclipse-temurin:17-jdk-jammy镜像,而非“jre”标签——因为哪怕只运行,也常需jstack、jstat等诊断工具
如何确认当前环境用的是 JDK 还是 JRE
关键看有没有 javac,以及 java -version 输出是否含 “Runtime Environment” 或 “Development Kit”。
- 运行
which javac(Linux/macOS)或where javac(Windows):若返回路径,说明在 JDK 路径下;若提示“未找到”,大概率是精简 JRE(或 PATH 没配对) - 执行
java -version:
– 输出含Java(TM) SE Runtime Environment且无Java Development Kit字样 → 可能是旧版独立 JRE
– 输出含Java(TM) SE Development Kit→ 是 JDK
– OpenJDK 输出通常为OpenJDK Runtime Environment或OpenJDK 64-Bit Server VM,需结合是否有javac判断 - JDK 11+ 中,
java --list-modules可查看模块列表;JRE 环境会缺失jdk.compiler、jdk.javadoc等模块
项目打包后运行,到底依赖 JDK 还是 JRE
只依赖 JRE 级别的能力:即 JVM + 标准类库(java.base、java.desktop 等)。但“JRE”本身已不是独立产物,实际依赖的是 JDK 发行版中附带的运行时子集。
立即学习“Java免费学习笔记(深入)”;
- 使用
javac编译生成的.class文件,只需兼容版本的 JVM 即可运行,无需javac - 如果代码用了
javax.tools.JavaCompiler(运行时编译)、com.sun.tools.javac(内部 API)、或jdeps/jlink构建的自定义运行时镜像,则必须有 JDK - Maven/Gradle 构建时,
mvn compile必须有JAVA_HOME指向 JDK;但mvn exec:java或启动 Spring Bootjava -jar app.jar只需 JVM,可用JAVA_HOME指向任意 JDK(含其内嵌 JRE) - 注意:某些 IDE(如 IntelliJ)会把
Project SDK设为 JDK,但运行配置里误选 “JRE” —— 实际仍是同一个物理目录,只是 IDE 内部做了模块过滤
JDK 17+ 的 jlink 和 jpackage 如何改变“JRE”概念
传统 JRE 是预置的完整运行时;而 jlink 允许按需组装最小化运行时镜像,jpackage 进一步打包成带原生启动器的目录或安装包——此时“JRE”变成项目专属、可分发的产物。
jdk-17.0.2/bin/jlink \ --module-path $JAVA_HOME/jmods \ --add-modules java.base,java.desktop,java.logging \ --output my-runtime
- 生成的
my-runtime目录就是轻量级“JRE”,只含指定模块,不含javac、jshell等开发工具 - 该目录下仍有
bin/java,可直接运行应用:./my-runtime/bin/java -jar app.jar -
jpackage会在该运行时基础上添加图标、服务注册、卸载逻辑等,最终用户完全感知不到“JDK/JRE”区别 - 这种模式下,
JAVA_HOME对最终用户已无意义;你交付的是“带 JVM 的应用”,不是“需要用户装 Java”的程序
真正容易被忽略的点:很多团队还在文档里写“请安装 JRE 1.8”,但用户装了 JDK 8 也能跑;反过来,若用了 var(JDK 10+)、record(JDK 14+)等语法,哪怕只运行,也必须用对应 JDK 版本——因为编译阶段已绑定语言特性,不是运行时能绕开的。










