10.4 实战:插入式注解处理器
JDK编译优化部分在本书中并没有设置独立的实战章节,因为我们开发程序,考虑的主要是程序会如何运行,很少会有针对程序编译的需求。也因为这个原因,在JDK的编译子系统里面,提供给用户直接控制的功能相对较少,除了第11章会介绍的虚拟机JIT编译的几个相关参数以外,我们就只有使用JSR-296中定义的插入式注解处理器API来对JDK编译子系统的行为产生一些影响。
但是笔者并不认为相对于前两部分介绍的内存管理子系统和字节码执行子系统,JDK的编译子系统就不那么重要。一套编程语言中编译子系统的优劣,很大程度上决定了程序运行性能的好坏和编码效率的高低,尤其在Java语言中,运行期即时编译与虚拟机执行子系统非常紧密地互相依赖、配合运作(第11章将主要讲解这方面的内容)。了解JDK如何编译和优化代码,有助于我们写出适合JDK自优化的程序。下面我们回到本章的实战中,看看插入式注解处理器API能实现什么功能。
10.4.1 实战目标
通过阅读Javac编译器的源码,我们知道编译器在把Java程序源码编译为字节码的时候,会对Java程序源码做各方面的检查校验。这些校验主要以程序“写得对不对”为出发点,虽然也有各种WARNING的信息,但总体来讲还是较少去校验程序“写得好不好”。有鉴于此,业界出现了许多针对程序“写得好不好”的辅助校验工具,如CheckStyle、FindBug、Klocwork等。这些代码校验工具有一些是基于Java的源码进行校验,还有一些是通过扫描字节码来完成,在本节的实战中,我们将会使用注解处理器API来编写一款拥有自己编码风格的校验工具:NameCheckProcessor。
当然,由于我们的实战都是为了学习和演示技术原理,而不是为了做出一款能媲美CheckStyle等工具的产品来,所以NameCheckProcessor的目标也仅定为对Java程序命名进行检查,根据《Java语言规范(第3版)》中第6.8节的要求,Java程序命名应当符合下列格式的书写规范。
类(或接口):符合驼式命名法,首字母大写。
方法:符合驼式命名法,首字母小写。
字段:
●类或实例变量:符合驼式命名法,首字母小写。
●常量:要求全部由大写字母或下划线构成,并且第一个字符不能是下划线。
上文提到的驼式命名法(Camel Case Name),正如它的名称所表示的那样,是指混合使用大小写字母来分割构成变量或函数的名字,犹如驼峰一般,这是当前Java语言中主流的命名规范,我们的实战目标就是为Javac编译器添加一个额外的功能,在编译程序时检查程序名是否符合上述对类(或接口)、方法、字段的命名要求[1]。
[1]在JDK的sample/javac/processing目录中有这次实战的源码(稍微复杂一些,但总体上差距不大),读者可以阅读参考。