Java 编译与运行过程
理解 Java 的编译和运行过程,有助于你更好地理解 Java 的工作原理,以及如何解决编译和运行中的问题。本章将详细介绍从源代码到程序执行的完整过程。
Java 源码 → 字节码 → JVM 执行
完整流程
Java 源代码 (.java)
↓
javac 编译器
↓
字节码 (.class)
↓
JVM(Java 虚拟机)
↓
机器码(JIT 编译)
↓
CPU 执行
↓
程序运行结果
详细步骤
1. 编写源代码
创建 .java 文件,编写 Java 代码:
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
2. 编译(Compilation)
使用 javac 编译器将源代码编译为字节码:
javac HelloWorld.java
编译过程:
- 词法分析:将源代码分解为标记(tokens)
- 语法分析:检查语法是否正确
- 语义分析:检查类型、作用域等
- 代码生成:生成字节码文件
结果:生成 HelloWorld.class 文件(字节码)
3. 加载(Loading)
JVM 加载 .class 文件:
- 类加载器:读取字节码文件
- 验证:检查字节码的正确性
- 准备:为类变量分配内存
- 解析:将符号引用转换为直接引用
4. 执行(Execution)
JVM 执行字节码:
- 解释执行:逐条解释字节码指令
- JIT 编译:将热点代码编译为机器码
- 运行:CPU 执行机器码
javac 与 java 命令使用
javac 命令
作用:编译 Java 源代码为字节码
基本用法
# 编译单个文件
javac HelloWorld.java
# 编译多个文件
javac File1.java File2.java File3.java
# 编译目录下所有文件
javac *.java
# 编译带包的文件
javac com/example/HelloWorld.java
常用选项
# -d:指定输出目录
javac -d out src/HelloWorld.java
# -cp 或 -classpath:指定类路径
javac -cp lib/*.jar src/HelloWorld.java
# -encoding:指定源文件编码
javac -encoding UTF-8 HelloWorld.java
# -source:指定源代码版本
javac -source 17 HelloWorld.java
# -target:指定目标字节码版本
javac -target 17 HelloWorld.java
# -verbose:显示详细信息
javac -verbose HelloWorld.java
编译示例
# 示例 1:基本编译
javac HelloWorld.java
# 生成:HelloWorld.class
# 示例 2:指定输出目录
javac -d classes src/HelloWorld.java
# 生成:classes/HelloWorld.class
# 示例 3:编译多个文件
javac -d out src/**/*.java
# 编译 src 目录下所有 .java 文件到 out 目录
java 命令
作用:运行编译后的 Java 程序
基本用法
# 运行类(无包)
java HelloWorld
# 运行带包的类
java com.example.HelloWorld
# 传递参数
java HelloWorld arg1 arg2
常用选项
# -cp 或 -classpath:指定类路径
java -cp .:lib/* com.example.HelloWorld
# -Xmx:设置最大堆内存
java -Xmx512m HelloWorld
# -Xms:设置初始堆内存
java -Xms256m HelloWorld
# -version:显示版本信息
java -version
# -verbose:显示详细信息
java -verbose:class HelloWorld
# -D:设置系统属性
java -Dkey=value HelloWorld
运行示例
# 示例 1:基本运行
java HelloWorld
# 输出:Hello, World!
# 示例 2:传递参数
java HelloWorld hello world
# args[0] = "hello", args[1] = "world"
# 示例 3:指定类路径
java -cp .:lib/*:out com.example.HelloWorld
类路径(classpath)概念
什么是类路径
类路径(classpath) 是 JVM 查找类文件的路径。当 JVM 需要加载一个类时,会在类路径中搜索对应的 .class 文件。
类路径的组成
类路径可以包含:
- 目录:包含
.class文件的目录 - JAR 文件:Java 归档文件
- ZIP 文件:压缩文件