Javac编译器的编译流程主要如下图:
各个阶段的作用:
词法分析:
主要的作用就是读入Java源代码文件,生成Token流,用到的类如下图:
Scanner调用nextToken()方法,返回一个Token。
Scanner它内部究竟是怎么获得Token的呢?
首先它会先把 Java源文件转为Char[]数组,逐个Char去判断,遇到单词分隔符(空格)、分隔语义时,分析出Java源文件中的词。再把分析出来的单词 Char[]数组传给Table.fromChars(chars)方法,Table会生成chars的hash值,也就是Table.hashs哈希表 的索引,当哈希表里不存在相应的Name时,生成新的一个Name,把它存入到哈希表Table.hashs中。再调用用 Keywords.key(name),直接由Keywords返回Token值。Keywords中存储的就是Name和Token的关系映射,它负责 将字符集合对应到Token。
语法分析:
主要把Token流组装成一棵基本的语法树。是一个递归下降且运算符优先级的语法分析器,使用com.sun.tools.javac.parser.Parser类,根据语法由Token序列生成相应的树节点,组装成抽象语法树。
语义分析:
语义分析包括:输入到符号表-> 注解处理->标注(Attr)和检查(Check)->数据流分析(Flow)->数据流分析(Flow)->转换类型:(TransTypes)-> 解除语法糖:(Lower)
输入到符号表:
使用com.sun.tools.javac.comp.Enter类,此过程每个编译单元的抽象语法树的顶局节点都先被放到待处理列表中并逐个处理列表中的节点
所有的类符号被输入到外围作用域的符号表中
确定类的参数(对泛型类型而言)、超类型和接口
如果需要添加默认构造器
将类中出现的符号输入到类自身的符号表中
分析和检查代码中的annotation
注解处理:annotation processing
使用com.sun.tools.javac.processing.JavacProcessingEnvironment类,并且支持用户自定义的annotation
编译时lombook对java文件进行编译之后会再次进入Parse and Enter步骤
标注(Attr)和检查(Check):
是语义分析的一个步骤,使用com.sun.tools.javac.comp.Attr类和com.sun.tools.javac.comp.Check类
主要作用有:
将语法树中名字、表达式等元素与变量、方法、类型等联系到一起
检查变量使用前是否已声明
推导泛型方法的类型参数
检查类型匹配性
进行常量折叠(将常量语法树合并)
数据流分析(Flow):
使用com.sun.tools.javac.comp.Flow类
检查所有语句都可到达
检查所有checked exception都被捕获或抛出
检查所有局部变量在使用前必项确定性赋值
检查有返回值的方法必须确定性返回值
检查变量的确定性且不重复赋值
转换类型:(TransTypes)
使用com.sun.tools.javac.comp.TransTypes主要作用是将泛型java代码转换成普通的java代码
eg:
List<Integer> list = Arrays.asList(1, 2, 3);
int i = list.get(0);
转换后:
List list = Arrays.asList(1, 2, 3);
int i = (Integer)list.get(0);为了保证泛型的语义,增加了强制类型转换
解除语法糖:(Lower)
使用com.sun.tools.javac.comp.Lower类
消除if(false){…}形式的无用代码
将含有语法糖的语法树改写为含有简单语言结构的语法树
eg
具名内部类,匿名内部类,类字面量
自动装箱拆箱
断言
foreach循环
enum或String类型的switch(java7)
eg:
List<Integer> list = Arrays.asList(1, 2, 3);
int i = list.get(0);
转换后:
List list = Arrays.asList(//自动装箱拆箱
new Integer[]{
Integer.valueOf(1),
Integer.valueOf(2),
Integer.valueOf(3)
}
);
int i = ((Integer)list.get(0)).intValue();
生成字节码:(Gen)
使用com.sun.tool.javac.jvm.Gen
将实例成员初始化器收集到构造器中成为<init>()
将静态成员初始化器收集为<clinit>()
从抽象语法树生成字节码
后序遍历语法树
进行最后的少量代码转换
String的+操作被生成为StringBuilder操作
x++/x–在条件允许时被优化为++x/–x
etc …
从符号表生成Class文件
生成Class文件的结构信息
生成元数据(包括常量池)
转载:http://beiden.me/archives/2660.htm
相关推荐
本资源是java 编译器 javac(java compilor) 的源代码,对于想深入学习 java 工作原理的开发人员来说是一个很好的资源,在此共享,还望喜欢。
java 编译器 源码 javac javac 编译器源代码
- 第10章 前端编译与优化10.2.4 语义分析与字节码生成经过语法分析之后,编译器获得了程序代码的抽象语法树表示,抽象语法树能够表示一个结构正确的源程序,但
因为Javac源代码放在了OPENJDK中,不是很容易找到,因此上传一份到CSDN中
源代码和注释详细,可供对java语言感兴趣的人学习使用。
java 源码分析 Javac-Research Java语言编译器(javac)源代码学习研究(包括代码注释、文档、用于代码分析的测试用例)
是在博客里写明的示例,方便如果想看的人可以下载,方便进行查看
编写Java源代码的示例; 打开命令提示符或终端的方法; 导航到Java源代码所在目录的步骤; 使用javac编译器编译Java程序的方法; 检查编译结果的方法。 内容概要: 编写示例源码; 打开命令提示符或终端; 导航到源...
jdk9 javac编译器 源码 当前可以根据用目录作为参数进行编译 谢谢
jdk9 javac编译器,从编译器解压出来的大包不能直接用于编译,会报package冲突,做了一些处理后可以用于本地编译和调试
编写Java源代码的示例; 使用javac编译器编译Java程序的方法; 使用java命令运行Java程序的方法。 内容概要: 编写示例源码; 使用javac编译器编译Java程序; 使用java命令运行Java程序。 阅读建议: 在编写Java源...
Java字节码生成器是在著名的工具Flex&Bison之上构建的编译器,用于接收任何Java源代码(当前仅支持Java Lang的子集)并发出其等效的字节码。 这是PLT开发(P AGC软件大号anguage牛逼ranslation)当然,在工程,...
sharmanka能够编译这些源代码,并仅使用javac编译器和用bash编写的业务逻辑为您调用程序的static void main()函数。 sharmanka很小而且很安全! 整个逻辑适合一个bash文件,安装后即可方便地使用。 用法 Sharmanka...
jphp, 除Zend 和Jython之外,另一种替代的方法 JPHP - PHP的一个实现 JPHP是PHP的新实现,它使用了 Java VM 。 它支持PHP语言( 7.0 )的...它是怎样工作的JPHP是 javac 编译器,它将php源代码编译为JVM字节码,然后在
:语义分析(也包括上下文敏感分析)是编译器构造过程中的一个过程,通常在解析后从源代码中收集必要的语义信息。 它通常包括类型检查,或确保在使用前声明了一个变量,该变量无法用扩展Backus–Naur形式描述,因此...
看不到源码Java 运算符重载 Java-OO 是用于 () 支持的 Java 编译器和 IDE 的模块化扩展(插件)。 适用于标准 JavaC 编译器、、、IDE 和任何构建工具。 示例(请参阅 dir 中的其他示例): import java.math.* ; ...
您将需要一个文本编辑器 .vi、gedit、sublimetext 、记事本、TextEdit、写字板等,只要它不在源代码的末尾附加“.txt”,就可以使用。 (对于Windows 用户) 4. 下载后,您需要在PATH 环境变量中添加一个条目,以便...
1.Java 编译器:JDK 提供了 Java 编译器 javac,用于将 Java 源代码编译成 Java 字节码。 2.Java 运行时环境:JDK 包含了 Java 虚拟机 (JVM),可以在计算机上运行编译后的 Java 字节码。 3.类库:JDK 8 包含了丰富的...
jdk-6u45-windows 64位官方正式版(附安装文档) ...javac – 编译器,将源程序转成字节码 jar – 打包工具,将相关的类文件打包成一个文件 javadoc – 文档生成器,从源码注释中提取文档 jdb – debugger,查错工具
2、编译源代码(javac.exe编译器) 3、执行编译文件(java.exe解释器) 4、交由JVM(java虚拟机执行) 3.3:编译运行 每次代码改变后都要重新编译一下,才能有运行结果 javac xx.java文件名 进行编译,将源程序转成...