咱们都知道 *.java 文件要首先被编译成 *.class 文件才能被 JVM 认识,这部分的工做主要由 Javac 来完成,相似于 Javac 这样的咱们称之为前端编译器;前端
可是 *.class 文件也不是机器语言,怎么才能让机器识别呢?就须要 JVM 将 *.class 文件编译成机器码,这部分工做由JIT 编译器完成;java
除了这两种编译器,还有一种直接把 *.java 文件编译成本地机器码的编译器,咱们称之AOT 编译器。git
首先,咱们先导一份 javac 的源码(基于 openjdk8)出来,下载地址:https://hg.openjdk.java.net/jdk8/jdk8/langtools/archive/tip.tar.gz,而后将 JDK_SRC_HOME/langtools/src/share/classes/com/sun 目录下的源文件所有复制到工程的源码目录中,生成的 目录 以下:
github
咱们执行 com.sun.tools.javac.Main 的 main 方法,就和咱们在命令窗口中使用 javac 命令同样:
ui
从 Sun Javac 的代码来看,编译过程大体能够分为三个步骤:.net
这三个步骤所作的工做内容大体以下:blog
这三个步骤之间的关系和交互顺序以下图所示,能够看到若是注解处理器在处理注解期间对语法树进行了修改,编译器将回到解析和填充符号表的过程进行从新处理,直到注解处理器没有再对语法树进行修改成止。ip
Javac 编译的入口是 com.sun.tools.javac.main.JavaCompiler 类,上述三个步骤的代码都集中在这个类的 compile() 和 compile2() 中:get