在Java里如何处理JDK与JRE的区别_Java运行环境概念解析

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”标签——因为哪怕只运行,也常需 jstackjstat 等诊断工具

如何确认当前环境用的是 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 Dev

    elopment Kit
    字样 → 可能是旧版独立 JRE
    – 输出含 Java(TM) SE Development Kit → 是 JDK
    – OpenJDK 输出通常为 OpenJDK Runtime EnvironmentOpenJDK 64-Bit Server VM,需结合是否有 javac 判断
  • JDK 11+ 中,java --list-modules 可查看模块列表;JRE 环境会缺失 jdk.compilerjdk.javadoc 等模块

项目打包后运行,到底依赖 JDK 还是 JRE

只依赖 JRE 级别的能力:即 JVM + 标准类库(java.basejava.desktop 等)。但“JRE”本身已不是独立产物,实际依赖的是 JDK 发行版中附带的运行时子集。

  • 使用 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 Boot java -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”,只含指定模块,不含 javacjshell 等开发工具
  • 该目录下仍有 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 版本——因为编译阶段已绑定语言特性,不是运行时能绕开的。