这篇文章按'结构流程'把 Java 程序从源码到运行的每一步串起来: 编译期(javac) → 运行期(java + JVM) → 类加载(ClassLoader) → 执行(解释器 + JIT)
0. 先定一个目标:Java 程序'运行'的定义是什么?
很多人说'运行 Java 文件',但更精确的说法是:
- JVM 不会直接执行
.java源文件 - JVM 执行的是
.class字节码(或者 jar 包里的 class)
因此,Java 程序跑起来至少经历两段:
- 编译期:
.java→javac→.class(字节码) - 运行期:
java启动 JVM → 类加载/链接/初始化 → 找到main→ 执行字节码(解释 + JIT)
1. 总体流程图:从源码到 JVM 退出(主线必须背)
.java 源码
javac 编译器
词法/语法/语义分析(可含注解处理)
输出 .class 字节码
java 命令启动器
创建 JVM 进程
初始化运行环境
定位主类 Main Class
ClassLoader 加载主类
Linking(链接)
验证 / 准备 / 解析
Initialization(初始化)
static 赋值 + static 块
调用 main(String[] args)
执行引擎执行字节码
解释器 + JIT
main 返回且无非守护线程
JVM 退出
2. .java 文件的结构:入口在哪里?
一个最小可运行 Java 程序的关键点在于 入口方法:
public class Hello {
public static void main(String[] args) {
System.out.println("hi");
}
}
- 程序入口是
public static void main(String[] args) java命令运行的是'主类的全限定名',不是文件名- 有包名:
java com.example.Hello - 没包名:
java Hello
- 有包名:
- 一个
.java文件可以写多个类,但public顶层类通常要求和文件名一致(Hello.java对应public class Hello)
3. 编译期:javac 做了什么?为什么是 .class?
3.1 你看到的命令
javac Hello.java

