CodeWalk

Javac编译器的工作流程与编译原理

作者:编译有声 · 2026-05-30 12:55

解释javac编译器的编译流程,包括词法分析、语法分析、语义分析、类型检查、注解处理(AbstractProcessor)、以及最终字节码生成的完整链路。

回答

编译有声

javac编译流程(4个阶段):

1. 词法分析(Lexical Analysis)

  • 组件:com.sun.tools.javac.parser.Scanner
  • 输入:源代码文件
  • 输出:Token流(关键字、标识符、运算符、字面量等)
  • Unicode转义处理(\uxxxx

2. 语法分析(Syntax Analysis)

  • 组件:com.sun.tools.javac.parser.Parser
  • 输入:Token流
  • 输出:AST(抽象语法树),节点类型为JCTree
  • 递归下降解析,支持错误恢复

3. 语义分析(Semantic Analysis) 包括多个子阶段:

  • Enter:填充符号表(Symbol Table),注册类和成员
  • Attr(Attribute):类型检查和解析
    • 检查类型兼容性、方法重载解析
    • 自动装箱/拆箱、泛型擦除
    • 常量折叠(Constant Folding)
  • Flow:控制流分析
    • 检查return/break/continue
    • 变量初始化检查(definite assignment)
  • TransTypes:泛型擦除,添加桥方法
  • Lower:语法糖解糖
    • 增强for→迭代器、try-with-resources→try-finally、内部类→外部类引用
    • lambda→invokedynamic + LambdaMetafactory
  • TODO:注解处理

4. 字节码生成(Code Generation)

  • 组件:com.sun.tools.javac.jvm.Gen
  • 输出:.class文件(魔数0xCAFEBABE + 常量池 + 方法字节码)
  • 本地变量表分配、操作数栈深度计算
  • 跳转指令优化(GOTO→ifeq等)

5. 注解处理(Annotation Processing)

  • Round-based处理,可多次迭代
  • javax.annotation.processing.AbstractProcessor
  • 可生成新的Java源文件(Lombok、MapStruct)