aas 从计算机程序出现的第一天起,对效率的追逐就是程序员天生的坚定信仰,这个过程犹如一场没有终点、永不停歇的F1方程式竞赛,程序员是车手,技术平台则是在赛道上飞驰的赛车。 asdsadasdasdasdsadasdasdasdsadassdasdsasdsadsdasdasdsadasdasdsadasdsadassadasdas————《Java虚拟机规范》
"编译期"到底指什么? aa 
aas[注]: aaasdas①、一般我们说的“前端”指的是由前端编译器完成的编译行为。 aa aaasdas②、Java虚拟机设计团队选择把对性能的优化全部集中到运行期的即时编译器中(这样可以让那些不是由Javac产生的Class文件(如JRuby、Groovy等语言的Class文件)也同样能享受到编译器优化措施所带来的性能红利)。 aa aaasdas③、相当多新生的Java语法特性,都是靠编译器的“语法糖”来实现,而不是依赖字节码或者Java虚拟机的底层改进来支持。 aa aaasdas总之:Java中即时编译器在运行期的优化过程,支撑了程序执行效率的不断提升;而前端编译器在编译期的优化过程,则是支撑着程序员的编码效率和语言使用者的幸福感的提高。
Javac编译器的相关知识: aa aasJavac编译器身就是一个由Java语言编写的程序。
das从Javac代码的总体结构来看,编译过程大致可以分为1个准备过程和3个处理过程: das dasdas①、准备过程:初始化插入式注解处理器。 das dasdas②、解析与填充符号表过程(词法、语法分析,构造出抽象语法树,填充符号表。产生符号地址和符号信息) das dasdas③、插入式注解处理器的注解处理过程 das dasdas④、分析与字节码生成过程(标注检查(对语法的静态信息进行检查)、数据流及控制流分析(对程序动态运行过程进行检查)、解语法糖(将简化代码编写的语法糖还原为原有的形式)、字节码生成(将前面各个步骤所生成的信息转化成字节码)) das dasdas上述3个处理过程里,执行插入式注解时又可能会产生新的符号,如果有新的符号产生,就必须转回到之前的解析、填充符号表的过程中重新处理这些新符号。  aas解析过程: 包括了经典程序编译原理中的词法分析和语法分析两个步骤: aa aaasdsas①、语法分析是将 源代码的字符流 转变为 标记集合 的过程。
aaasdasdsasas⒈单个字符是程序编写时的最小元素,但标记才是编译时的最小元素,键字、变量名、字面量、运算符都可以作为标记。
aaasdasdsasas⒉比如,“int a=b+2”这句代码中就包含了6个标记,分别是int、a、=、b、+、2。 aa aaasdsas②、语法分析是根据标记序列构造抽象语法树的过程,抽象语法树是一种用来描述程序代码语法结构的树形表示方式,抽象语法树的每一个节点都代表着程序代码中的一个语法结构,例如包、类型、修饰符、运算符、接口、返回值甚至连代码注释等都可以是一种特定的语法结构。 aa aas填充符号表过程: 完成了语法分析和词法分析之后,下一个阶段是对符号表进行填充的过程。 aa aaasdsas①、符号表是由一组符号地址和符号信息构成的数据结构,读者可以把它类比想象成哈希表中键值对的存储形式(实际上符号表不一定是哈希表实现,可以是有序符号表、树状符号表、栈结构符号表等各种形式) aa aaasdsas②、符号表中所登记的信息在编译的不同阶段都要被用到。譬如在语义分析的过程中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的声明是否一致)和产生中间代码,在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的直接依据。 aa aas注解处理器: aa aaasdsas①、JDK 5之后,Java语言提供了对注解的支持,注解在设计上原本是与普通的Java代码一样,都只会在程序运行期间发挥作用的。 aa aaasdsas②、但在JDK 6中又设计了一组被称为“插入式注解处理器”的标准API,可以提前至编译期对代码中的特定注解进行处理,从而影响到前端编译器的工作过程。
aasadsas[注]: aasasdsaasas⒈我们可以把插入式注解处理器看作是一组编译器的插件,当这些插件工作时,允许读取、修改、添加抽象语法树中的任意元素。如果这些插件在处理注解期间对语法树进行过修改,编译器将回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止,每一次循环过程称为一个轮次。 aasdsasadsas⒉有了编译器注解处理的标准API后,程序员的代码才有可能干涉编译器的行为,由于语法树中的任意元素,甚至包括代码注释都可以在插件中被访问到,所以通过插入式注解处理器实现的插件在功能上有很大的发挥空间。只要有足够的创意,程序员能使用插入式注解处理器来实现许多原本只能在编码中由人工完成的事情。 aasdsasadsas⒊比如Java著名的编码效率工具Lombok,它可以通过注解来实现自动产生getter/setter方法、进行空置检查、生成受查异常表、产生equals()和hashCode()方法,等等,帮助开发人员消除Java的冗长代码,这些都是依赖插入式注解处理器来实现的。 aa aas语义分析与字节码生成: aa aaasdsas
|