本篇博文来自于《深入理解Java虚拟机--JVM高级特性与最佳实践》一书。我们使用注解处理器API来编写一款拥有自己编码风格的代码校验工具:NameCheckProcessor.

java程序命名规范应当符合下列格式的书写规范:

1  类或接口:符合驼式命名法,首字母大写

2  方法:符合驼式命名法,首字母小写

3  字段

1)类或实例变量:符合驼式命名法,首字母小写

2)常量:要求全部由大写字母或下划线构成,并且第一个字母不能是下划线

代码实现:

注解处理器:NameCheckProcessor

import java.util.Set;import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;/*** * @author Administrator* */// 可以用"*"支持所有的Annotations
@SupportedAnnotationTypes("*")
// 只支持1.6的java代码
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class NameCheckProcessor extends AbstractProcessor {private NameChecker nameChecker;/*** 初始化名称检查插件*/@Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);nameChecker = new NameChecker(processingEnv);}/*** 对输入的语法树的各个节点进行名称检查*/@Overridepublic boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {if (!roundEnv.processingOver()) {for (Element element : roundEnv.getRootElements()) {nameChecker.checkNames(element);}}return false;}}

命名检查器:NameChecker

import java.util.EnumSet;import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementScanner6;
import javax.tools.Diagnostic.Kind;/*** 程序名称规范的编译器插件 如果程序名称不符合规范,则输出一个编译器的WARNING信息* * @author Administrator* */
public class NameChecker {private final Messager messager;NameCheckScanner nameCheckScanner = new NameCheckScanner();public NameChecker(ProcessingEnvironment processingEnv) {this.messager = processingEnv.getMessager();}/*** * 对java程序命名进行检查,java名称命名应符合如下格式:* <ul>* <li>类或接口:符合驼式命名法,首字母大写* <li>方法:符合驼式命名法,首字母小写* <li>字段:符合驼式命名法,首字母小写* <li>类、实例变量:符合驼式命名法,首字母小写* <li>常量:要求全部大写* </ul>* */public void checkNames(Element element) {nameCheckScanner.scan(element);}/*** 名称检查器实现类,继承了jdk1.6中新提供的ElementScanner6<br>* 将会以Visitor模式访问抽象语法树中的元素* */private class NameCheckScanner extends ElementScanner6<Void, Void> {/*** 此方法用于检查java类*/@Overridepublic Void visitType(TypeElement e, Void p) {scan(e.getTypeParameters(), p);checkCamelCase(e, true);super.visitType(e, p);return null;}/*** 检查方法命名是否合法*/@Overridepublic Void visitExecutable(ExecutableElement e, Void p) {if (e.getKind() == ElementKind.METHOD) {Name name = e.getSimpleName();if (name.contentEquals(e.getEnclosingElement().getSimpleName()))messager.printMessage(Kind.WARNING, " 一个普通方法 '" + name + "' 不应该与类名相同,避免与构造方法产生混淆", e);checkCamelCase(e, false);}super.visitExecutable(e, p);return null;}/*** 检查变量命名是否合法*/@Overridepublic Void visitVariable(VariableElement e, Void p) {if (e.getKind() == ElementKind.ENUM_CONSTANT || e.getConstantValue() != null || heuristicallyConstant(e))checkAllCaps(e);elsecheckCamelCase(e, false);return null;}/*** 判断一个变量是否是常量* * @param e* @return*/private boolean heuristicallyConstant(VariableElement e) {if (e.getEnclosingElement().getKind() == ElementKind.INTERFACE)return true;else if (e.getKind() == ElementKind.FIELD&& e.getModifiers().containsAll(EnumSet.of(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)))return true;else {return false;}}/*** 检查传入的Element是否符合驼式命名法,如果不符合则输出警告信息* * @param e* @param initialCaps*/private void checkCamelCase(Element e, boolean initialCaps) {String name = e.getSimpleName().toString();boolean previousUpper = false;boolean conventional = true;int firstCodePoint = name.codePointAt(0);if (Character.isUpperCase(firstCodePoint)) {previousUpper = true;if (!initialCaps) {messager.printMessage(Kind.WARNING, "名称  '" + name + " ' 应当以小写字母开头", e);return;}} else if (Character.isLowerCase(firstCodePoint)) {if (initialCaps) {messager.printMessage(Kind.WARNING, "名称  '" + name + " ' 应当以大写字母开头", e);return;}} elseconventional = false;if (conventional) {int cp = firstCodePoint;for (int i = Character.charCount(cp); i < name.length(); i += Character.charCount(cp)) {cp = name.codePointAt(i);if (Character.isUpperCase(cp)) {if (previousUpper) {conventional = false;break;}previousUpper = true;} elsepreviousUpper = false;}}if (!conventional)messager.printMessage(Kind.WARNING, "名称  '" + name + " ' 应当符合驼式命名法", e);}/*** 大写命名检查,要求第一个字母是大写的英文字母,其余部分是大写字母或下划线* * @param e*/private void checkAllCaps(VariableElement e) {String name = e.getSimpleName().toString();boolean conventional = true;int firstCodePoint = name.codePointAt(0);if (!Character.isUpperCase(firstCodePoint)) {conventional = false;} else {boolean previousUnderscore = false;int cp = firstCodePoint;for (int i = Character.charCount(cp); i < name.length(); i += Character.charCount(cp)) {cp = name.codePointAt(i);if (cp == '_') {if (previousUnderscore) {conventional = false;break;}previousUnderscore = true;} else {previousUnderscore = false;if (!Character.isUpperCase(cp) && !Character.isDigit(cp)) {conventional = false;break;}}}}if (!conventional)messager.printMessage(Kind.WARNING, "常量  '" + name + " ' 应当全部以大写字母或下划线命名,并且以字母开头", e);}}}

自己动手编写java编译器相关推荐

  1. 编写Java哪个编译器好

    现在能够编写Java代码的工具简直不要太多,各种各样五花八门,但目前效率最高的还是Intellij Idea.但这个工具对于完全零基础的小白来说,第一次用起来是比较复杂的,因为它的功能太多了.这就好比 ...

  2. 编写运行最简单的java程序——使用记事本编写java程序

    编写运行最简单的java程序--使用记事本编写java程序 第一个java程序--使用记事本编辑 经过上篇文章的java环境搭建成功的小伙伴们可以在自己的计算机上编写属于自己的java程序了yo~ 还 ...

  3. java编译器使用教程_Java编译器API简介

    今天给大家分享的是Java编译器API简介,文章部分内容摘自[优锐课]学习笔记. Java编译器API Java编译器API是Java模块(称为java.compiler)的一部分.该模块包括语言模型 ...

  4. java arm 编译器下载_最全盘点:18款在线C/C++/Py/Java编译器,一个比一个强大(附地址)...

    1.Ideone Ideone是C / C ++,Java,PHP,Python,Perl和40+编译器和解释器,支持其他的60种语言.这个工具提供许多强大的功能,允许程序员快速高效的编译源代码.在编 ...

  5. 灵魂拷问:用移位来代替除法运算真的效率高吗?Java 编译器到底有没有做除法优化?

    目录 引入 C++ 编译器对除法的优化 Java 编译器对除法的优化 移位运算对应的字节码 除法操作对应的字节码 查看及分析 JIT 即时编译结果 1.手动编译 OpenJDK 2.编译 hsdis- ...

  6. java平台脚本+java编译器API

    [0]README 0.1)本文文字描述转自 core java volume 2, 旨在学习  java平台脚本+java编译器API 的 基础知识: ----------------------- ...

  7. java编译器jdk版本_以编程方式确定Java类的JDK编译版本

    java编译器jdk版本 当需要确定使用哪个JDK版本来编译特定的Java .class文件时, 通常使用的方法是使用javap并在javap输出中查找列出的"主要版本". 我在我 ...

  8. java编译器分析_Java反编译器的剖析

    java编译器分析 简单地说,反编译器尝试将源代码转换为目标代码. 但是有很多有趣的复杂性-Java源代码是结构化的: 字节码当然不是. 而且,转换不是一对一的:两个不同的Java程序可能会产生相同的 ...

  9. linux的静态编译elf无法调试,[翻译]自己动手编写一个Linux调试器系列之4 ELF文件格式与DWARF调试格式 by lantie@15PB...

    自己动手编写一个Linux调试器系列之4 ELF文件格式与DWARF调试格式 by lantie@15PB 在上一节中,你已经听说了DWARF调试格式,它是程序的调试信息,是一种可以更好理解源码的方式 ...

最新文章

  1. 线性代数:04 特征值与特征向量 -- 矩阵的相似对角化
  2. 如何使用facenet
  3. Ext.Net学习笔记19:Ext.Net FormPanel 简单用法
  4. Flutter入门:Image组件
  5. 【模板】吉老师线段树
  6. git 中文乱码配置
  7. idea 修改样式要编译_在IDEA中DEBUG Javac源码
  8. 马吕斯定律matlab拟合,Matlab插值模拟在光的偏振中的应用
  9. 线性逻辑回归logistic regression
  10. 谷歌修复4个已遭利用的安卓 0day
  11. C++笔试题 String类的实现 三大复制控制函数
  12. 软件推荐┊最有效防止被聚生网管、P2P终结者等管理软件控制的小工具——ARP防火墙单机版...
  13. 微信小程序解密encryptedData 报错:pad block corrupted 解决方法
  14. 努力赚钱,是为了不让自己的爱情受到别人金钱的考验--这就是现实
  15. CPU降频实现原理与试验数据
  16. 一些关于网页设计的优秀网站
  17. bps pps fps的定义
  18. 正点原子ESP8266的使用
  19. 【网络安全】上网行为管理
  20. 什么是僵死进程(Zombies)

热门文章

  1. 【硬件】硬件随机失效定量分析
  2. 记录一次wine安装(下列软件包有未满足的依赖关系: winehq-stable : 依赖: wine-stable (= 5.0.0~bionic))
  3. 防火卷帘门算料计算公式
  4. 图片文字转换word文字
  5. 云计算的概念,发展现状,实现机制,Google云计算原理
  6. 【千呼万唤】李宏毅《机器学习》国语课程(2022)终于来了
  7. Python去掉列表中的 ‘ | ’ |竖线分隔符
  8. 1MB等于多少BYTE?8086/8088寻址段地址与偏移地址解释
  9. 浅谈基于SDL的2D纵版弹幕射击游戏相关经验心得
  10. 6.以表格单据式单表为模板定制模块:订单信息维护