引言
为什么要学习这个主题?
当你第一次学习Java时,可能遇到过这些困惑:
- 下载Java时,看到JDK、JRE、JVM,该选哪个?
- 为什么有人说"装JDK就够了"?
- JDK和JRE有什么区别?为什么JDK更大?
这些问题看似简单,但很多开发者对三者的关系理解模糊。就像区分"汽车"、“发动机”、“汽车制造工厂"一样,理解它们的区别对配置开发环境至关重要。
你将学到什么?
- ✅ JVM、JRE、JDK的准确定义
- ✅ 三者的包含关系和依赖关系
- ✅ 什么时候需要JDK,什么时候只需JRE
- ✅ 如何选择和配置Java环境
- ✅ OpenJDK vs Oracle JDK的区别
一、核心概念定义
1.1 JVM(Java Virtual Machine)
定义:Java虚拟机,负责执行字节码的运行时环境。
职责:
- 加载和执行字节码
- 管理内存(堆、栈等)
- 垃圾回收
- 提供安全机制
类比:发动机
- 提供运行动力
- 是核心执行部件
- 但单独无法工作
独立使用:❌ 不能单独使用
- JVM需要配合类库才能运行Java程序
1.2 JRE(Java Runtime Environment)
定义:Java运行时环境,包含JVM和Java核心类库。
组成:
JRE = JVM + Java核心类库 + 支持文件
包含内容:
- JVM(如HotSpot)
- Java标准库(rt.jar等)
- 配置文件
- 属性设置
职责:
- 运行已编译的Java程序(.class文件)
类比:汽车(完整的运行系统)
- 有发动机(JVM)
- 有座椅、方向盘(类库)
- 可以正常行驶(运行程序)
独立使用:✅ 可以
- 如果只需要运行Java程序(不开发),只装JRE即可
1.3 JDK(Java Development Kit)
定义:Java开发工具包,包含JRE和开发工具。
组成:
JDK = JRE + 编译器(javac) + 调试器 + 其他开发工具
包含内容:
- 完整JRE
- javac:Java编译器
- javap:字节码反汇编器
- jdb:调试器
- javadoc:文档生成器
- jar:打包工具
- jconsole、jvisualvm:监控工具
- …更多开发工具
职责:
- 开发Java程序(编写、编译、调试、打包)
- 运行Java程序(包含JRE功能)
类比:汽车制造工厂
- 有完整的汽车(JRE)
- 有生产设备(javac编译器)
- 有测试工具(调试器)
- 有打包流水线(jar工具)
独立使用:✅ 可以
- JDK包含JRE的所有功能
- 开发者只需安装JDK
二、三者的包含关系
2.1 层次关系图
┌────────────────────────────────────────────────┐
│ JDK │ 开发工具包
│ ┌──────────────────────────────────────────┐ │
│ │ 开发工具 │ │
│ │ - javac (编译器) │ │
│ │ - javap (反汇编器) │ │
│ │ - jdb (调试器) │ │
│ │ - jar (打包工具) │ │
│ │ - javadoc (文档生成) │ │
│ │ - jconsole/jvisualvm (监控工具) │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ JRE │ │ 运行时环境
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ Java核心类库 │ │ │
│ │ │ - java.lang.*, java.util.* │ │ │
│ │ │ - java.io.*, java.net.* │ │ │
│ │ │ - javax.* ... │ │ │
│ │ └────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ JVM │ │ │ 虚拟机
│ │ │ - 类加载器 │ │ │
│ │ │ - 运行时数据区 │ │ │
│ │ │ - 执行引擎 │ │ │
│ │ │ - 垃圾收集器 │ │ │
│ │ └────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────┘ │
└────────────────────────────────────────────────┘
总结:JDK ⊃ JRE ⊃ JVM
2.2 关系说明
JVM(虚拟机)
↓ 被包含在
JRE(运行环境)= JVM + 类库
↓ 被包含在
JDK(开发工具包)= JRE + 开发工具
重要理解:
- JVM是核心,但不能单独使用
- JRE = JVM + 类库,可以运行Java程序
- JDK = JRE + 开发工具,可以开发和运行Java程序
三、使用场景对比
3.1 什么时候需要什么?
| 角色 | 需求 | 安装什么 | 原因 |
|---|---|---|---|
| 普通用户 | 运行Java程序(如Minecraft) | JRE | 只需运行,不需开发 |
| 开发者 | 开发Java程序 | JDK | 需要编译、调试、打包 |
| 服务器 | 部署Java应用(如Tomcat) | JRE(推荐)或JDK | 生产环境可只用JRE |
| CI/CD | 自动构建和测试 | JDK | 需要编译和打包 |
3.2 目录结构对比
JRE目录结构
jre/
├── bin/ # 可执行文件
│ ├── java # Java运行命令
│ └── ...
├── lib/ # 类库和配置
│ ├── rt.jar # 核心类库
│ ├── jce.jar # 加密扩展
│ └── ...
└── legal/ # 许可证文件
JDK目录结构
jdk/
├── bin/ # 可执行文件
│ ├── java # Java运行命令 ✅
│ ├── javac # 编译器 ✅
│ ├── javap # 反汇编器 ✅
│ ├── jar # 打包工具 ✅
│ ├── jdb # 调试器 ✅
│ ├── jconsole # 监控工具 ✅
│ └── ... # 更多开发工具
├── jre/ # 包含完整JRE ✅
│ ├── bin/
│ └── lib/
├── lib/ # JDK额外的类库
│ ├── tools.jar # 开发工具类库
│ └── ...
├── include/ # 本地开发头文件
└── legal/
说明:
- JDK的bin目录有更多工具
- JDK包含完整的jre目录
3.3 文件大小对比
以Java 17为例:
| 组件 | 大小 | 说明 |
|---|---|---|
| JVM(HotSpot) | ~30-50MB | 核心虚拟机 |
| JRE | ~150-200MB | JVM + 类库 |
| JDK | ~300-350MB | JRE + 开发工具 |
结论:JDK比JRE大约大100-150MB(开发工具的大小)
四、实战:配置Java开发环境
4.1 开发者安装指南
步骤1:下载JDK
推荐来源:
- Adoptium(推荐):https://adoptium.net/
- 免费、开源、长期支持
- Oracle JDK:https://www.oracle.com/java/technologies/downloads/
- 需要商业许可(生产环境)
- Amazon Corretto:https://aws.amazon.com/corretto/
- AWS提供的免费OpenJDK
- Microsoft Build of OpenJDK:https://www.microsoft.com/openjdk
- 微软提供的OpenJDK
步骤2:安装JDK
# macOS(使用Homebrew)
brew install openjdk@17
# Linux(Ubuntu)
sudo apt update
sudo apt install openjdk-17-jdk
# Windows
# 下载安装包,双击安装,按提示操作
步骤3:配置环境变量
macOS/Linux:
# 编辑 ~/.zshrc 或 ~/.bashrc
export JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk-17.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
Windows:
1. 右键"此电脑" → "属性" → "高级系统设置" → "环境变量"
2. 新建系统变量:
- 变量名:JAVA_HOME
- 变量值:C:\Program Files\Java\jdk-17
3. 编辑Path变量,添加:
- %JAVA_HOME%\bin
步骤4:验证安装
# 查看Java版本
java -version
# 查看Javac版本
javac -version
# 查看JAVA_HOME
echo $JAVA_HOME # macOS/Linux
echo %JAVA_HOME% # Windows
成功输出示例:
java version "17.0.9" 2023-10-17 LTS
Java(TM) SE Runtime Environment (build 17.0.9+11-LTS-201)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.9+11-LTS-201, mixed mode)
javac 17.0.9
4.2 服务器部署建议
生产环境推荐:只安装JRE(减少攻击面)
Docker示例:
# 方案1:完整JDK(开发/测试环境)
FROM openjdk:17-jdk-slim
COPY target/app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
# 方案2:只有JRE(生产环境,推荐)
FROM openjdk:17-jre-slim
COPY target/app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
容器大小对比:
openjdk:17-jdk-slim → 约420MB
openjdk:17-jre-slim → 约270MB ← 节省150MB
五、OpenJDK vs Oracle JDK
5.1 OpenJDK
性质:开源、免费
特点:
- 完全开源(GPL v2许可证)
- 社区驱动
- 更新频繁
- 无需商业许可
来源:
- Adoptium(推荐)
- Amazon Corretto
- Microsoft Build of OpenJDK
- Red Hat OpenJDK
5.2 Oracle JDK
性质:商业版,需许可证
特点:
- Oracle官方支持
- 长期支持(LTS)
- 性能优化
- 生产环境需商业许可(Oracle Java SE Subscription)
许可证变更:
JDK 8 (2014-2019):免费
JDK 9-10 (2017-2018):免费
JDK 11+ (2018-):生产环境需商业许可(除非使用OpenJDK)
5.3 功能对比
| 特性 | OpenJDK | Oracle JDK |
|---|---|---|
| 核心功能 | ✅ 完全相同 | ✅ 完全相同 |
| 性能 | ✅ 基本相同 | ✅ 略有优化 |
| 开源 | ✅ 是 | ❌ 部分闭源 |
| 商业支持 | ❌ 无(社区支持) | ✅ 有 |
| 生产环境 | ✅ 免费 | ❌ 需付费 |
| 长期支持 | ✅ 有(Adoptium、Corretto等) | ✅ 有 |
5.4 选择建议
| 场景 | 推荐 | 原因 |
|---|---|---|
| 个人学习 | OpenJDK | 免费、功能完整 |
| 开源项目 | OpenJDK | 无许可证风险 |
| 商业项目 | OpenJDK(Adoptium) | 免费、长期支持 |
| 大型企业 | Oracle JDK 或 OpenJDK | 根据支持需求选择 |
结论:大多数情况下,OpenJDK足够了。
六、版本选择策略
6.1 Java版本演进
Java 8 (LTS) → 2014年发布,使用最广泛
↓
Java 11 (LTS) → 2018年发布,企业主流
↓
Java 17 (LTS) → 2021年发布,新项目推荐
↓
Java 21 (LTS) → 2023年发布,最新LTS
LTS(Long-Term Support):长期支持版本
- 提供至少8年的更新和支持
- 稳定性高
- 生产环境首选
非LTS版本:
- 仅支持6个月
- 包含实验性特性
- 不推荐用于生产
6.2 版本选择建议
| 场景 | 推荐版本 | 原因 |
|---|---|---|
| 新项目 | Java 17 或 21 | 最新特性、长期支持 |
| 维护旧项目 | Java 8 或 11 | 保持兼容性 |
| 学习 | Java 17 | 平衡新旧特性 |
| Android开发 | Java 8 兼容 | Android API限制 |
6.3 升级策略
渐进式升级:
Java 8 → Java 11 → Java 17 → Java 21
每一步都需要:
- 测试兼容性
- 更新依赖库
- 调整JVM参数
- 验证性能
总结
核心要点回顾
三者关系
- JVM:虚拟机核心
- JRE = JVM + 类库(运行环境)
- JDK = JRE + 开发工具(开发工具包)
使用建议
- 开发者:安装JDK
- 普通用户:安装JRE(如果只运行程序)
- 服务器:JRE足够(生产环境)
版本选择
- 新项目:Java 17 或 21 (LTS)
- OpenJDK vs Oracle JDK:OpenJDK足够
配置要点
- 设置JAVA_HOME环境变量
- 将bin目录加入PATH
- 验证java和javac命令
思考题
- 为什么JDK包含JRE,而不是JRE包含JDK?
- 如果只安装JRE,能编译Java代码吗?为什么?
- Docker容器部署时,为什么推荐使用JRE而不是JDK?
第一阶段总结
恭喜!你已经完成了基础认知篇的所有文章。现在你应该:
- ✅ 理解Java程序的运行机制
- ✅ 掌握JVM的本质和分类
- ✅ 了解JVM的内部架构
- ✅ 理解字节码的格式和作用
- ✅ 能够区分JVM、JRE、JDK
下一阶段预告
第二阶段《类加载机制篇》,我们将深入探讨:
- 类加载的完整生命周期
- 类加载器的层次结构
- 双亲委派模型的原理
- 如何自定义类加载器
- 类加载的时机和触发条件
参考资料
- OpenJDK官网
- Adoptium (Eclipse Temurin)
- Oracle JDK下载
- 《深入理解Java虚拟机(第3版)》- 周志明
- Which Version of JDK Should I Use?
欢迎在评论区分享你的Java环境配置经验!