编译与运行
全流程概览
┌──────────┐ javac ┌──────────┐ ClassLoader ┌──────────┐
│ .java │ ─────────→ │ .class │ ──────────────→ │ JVM │
│ 源代码 │ │ 字节码 │ │ 执行 │
└──────────┘ └──────────┘ └──────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
解释执行 JIT 编译 GC
Java 程序经历两次”编译”:
- javac:源码 → 字节码(平台无关的中间表示)
- JIT:字节码 → 本地机器码(运行时热点优化)
编译阶段
javac 将 .java 文件编译为 .class 字节码,主要阶段:
| 阶段 | 说明 |
|---|---|
| 词法分析 | 将字符流切分为 Token |
| 语法分析 | 构建抽象语法树(AST) |
| 语义分析 | 类型检查、符号解析、注解处理 |
| 字节码生成 | 将 AST 转为 JVM 指令集 |
编译产物 .class 文件包含:
- 魔数
0xCAFEBABE(文件格式标识) - 版本号(major/minor version)
- 常量池
- 字段、方法描述
- 字节码指令
运行阶段
JVM 启动后通过 ClassLoader 按需加载 .class 文件,经历:
加载(Loading)→ 链接(Linking)→ 初始化(Initialization)→ 执行
│
┌───────┼────────┐
验证 准备 解析
执行引擎默认混合模式:
- 解释执行(启动快)
- JIT 编译热点方法为机器码(运行快)
详见 JVM 内存结构与类加载机制。
快速参考
# 编译单个文件
javac Hello.java
# 指定输出目录与源码编码
javac -d out -encoding UTF-8 Hello.java
# 编译时保留调试信息
javac -g Hello.java
# 运行
java -cp out Hello
# 查看字节码
javap -c -verbose out/Hello.class相关工具
| 工具 | 用途 |
|---|---|
| javac | 源码编译器 |
javap | 字节码反汇编 |
| fernflower | 字节码反编译为 Java 源码 |
| CFG | 编译器/JIT 内部控制流图 |
| JVM | 字节码执行环境 |
| JIT | 即时编译优化 |