Java开发者在搭建环境时,常会碰到JDK与JRE这两个名词。简单来说,JRE负责让Java程序运行,JDK负责把Java源码变成可运行的程序,同时也会附带上JRE。理解它们的组成,是配置环境与排查故障的基础。

JRE的组成与定位
JRE全称为Java Runtime Environment,也就是Java运行时环境。它面向的是已经编译完成的Java应用程序使用者,而不是开发者。只要机器上安装了对应版本的JRE,就可以执行打包好的jar文件或class文件,不需要关心源码是怎么写的。
从目录结构看,JRE主要包含两部分:一是Java虚拟机,也就是常说的JVM,它负责把字节码翻译成当前操作系统能执行的指令;二是核心类库,例如java.lang、java.util等基础包,它们以jar形式放在lib目录中。在JRE的bin目录下,最核心的命令就是java,用来启动虚拟机并加载程序。
下面是一个仅使用JRE就能运行的场景示例,假设我们已经有编译后的Main.class:
# 只安装JRE的环境变量检查 java -version # 直接运行已有class文件 java Main
可以看到,没有javac也能完成运行,这正是JRE的设计目的。它把开发工具剥离,减小体积,专注执行。
JDK的组成与定位
JDK全称为Java Development Kit,即Java开发工具包。它不仅是运行环境,更是一整套开发套件。安装JDK后,其目录里会包含一个完整的JRE子目录,此外还有bin中的编译器javac、打包工具jar、文档生成javadoc以及调试工具jdb等。
开发者写好的.java源文件,必须先通过javac编译成.class字节码,这一步只能由JDK提供。JRE本身没有编译能力。因此,任何写代码、做构建的机器都必须装JDK,而生产服务器如果只跑服务,理论上升级到只装JRE也能节省空间,不过现在很多部署方式直接带JDK以方便排查。
下面的代码展示了用JDK从源码到运行的完整链路:
// 源文件 Hello.java
public class Hello {
public static void main(String[] args) {
System.out.println("由JDK编译运行");
}
}
# 使用JDK的javac编译 javac Hello.java # 使用java命令运行,底层调用JRE java Hello
如果没有JDK,第一步javac就会报命令找不到,这直观体现了二者的能力边界。
二者关系与选择建议
从包含关系上看,JDK包含JRE,JRE包含JVM加类库。可以用一张简单表格说明差异:
| 对比项 | JDK | JRE |
|---|---|---|
| 是否含编译器 | 有javac | 无 |
| 是否含JVM | 含(通过内嵌JRE) | 含 |
| 适用角色 | 开发者 | 程序使用者 |
| 体积 | 较大 | 较小 |
在实际项目中,本地开发机毫无疑问装JDK。至于线上容器,若采用Spring Boot这类自带依赖的fat jar,用JRE运行即可;但若需要在服务器上现场编译脚本或用工具诊断,保留JDK更省心。另外注意,版本要匹配,用JDK 8编的程序放到只支持JRE 7的环境会抛出版本不支持错误。
理清JDK与JRE的组成,还能帮你看懂很多报错。例如提示找不到tools.jar,说明你用的环境是纯JRE,而某些构建工具需要JDK里的类。此时补装JDK而非JRE就能解决。
常见误区说明
有人以为JRE里也有编译器,只是没暴露命令,这是错的。JRE的bin中确实没有javac,也没有源码级调试接口。另一个误区是认为装了JDK就不用管JRE,其实JDK内部的jre目录就是它自带的运行环境,系统变量若配错,可能用到了旧JRE跑新代码。
建议配置JAVA_HOME指向JDK根目录,并把%JAVA_HOME%/bin放在PATH最前,这样既能用javac也能用java,且版本统一。若只配了JRE路径,协作时别人拉下代码就编不过,徒增沟通成本。
总结来看,JDK和JRE的区别核心在开发能力的有无,而不是运行能力的强弱。JRE专注执行,JDK覆盖开发到执行的全流程。按角色选包,按版本配路径,Java环境就能稳稳当当。