当前位置: 首页 > news >正文

河南省建设厅职称网站做虚假彩票网站判几年

河南省建设厅职称网站,做虚假彩票网站判几年,wordpress 自带主题,长沙互联网销售企业联系电话JDK 的编译子系统暴露给用户直接控制的功能相对很少,除了虚拟机即时编译的若干参数,便只有 JSR-296 中定义的插入式注解处理器 API; 文章目录1. 目标2. 实现3. 运行与测试4. 其他应用案例1. 目标 前端编译器在讲 Java 源码编译成字节码时对源…

JDK 的编译子系统暴露给用户直接控制的功能相对很少,除了虚拟机即时编译的若干参数,便只有 JSR-296 中定义的插入式注解处理器 API;

文章目录

      • 1. 目标
      • 2. 实现
      • 3. 运行与测试
      • 4. 其他应用案例

1. 目标

前端编译器在讲 Java 源码编译成字节码时对源码做了各方面检查,主要是看程序写到对不对,较少去看写得好不好,业界有一些如 CheckStyle、FindBug、Klocwork 等的工具用于检查代码好坏,有一些用于扫描 Java 源码,也有一些是扫描字节码;我们的目标是通过注解处理器 API 实现自己编码风格的校验工具:NameCheckProcessor

根据《Java 语言规范》要求,Java 程序命名推荐使用如下书写规范:

  • 类(接口):驼峰命名法,首字母大写;
  • 方法:驼峰命名法,首字母小写;
  • 字段
    • 类或实例变量:驼峰命名法,首字母小写;
    • 常量:全部由大写字母或下划线构成,第一个字符不能是下划线;

为 javac 编译器添加额外的功能,在编译程序时检查程序名是否符合上述对类、接口、方法、字段的命名要求;

2. 实现

注解处理器可以通过继承抽象类 javax.annotation.processing.AbstractProcessor 复写抽象方法 process() 来实现;javac 编译器在执行注解处理器代码时会调用 process()

  • annotations,此注解处理器所要处理的注解集合;
  • roundEnv,当前这个轮次(Round)中的抽象语法树节点,每个语法树节点表示一个 Element;
  • processingEnv,AbstractProcessor 中的一个 protected 变量,代表了注解处理器框架提供的一个上下文环境,可用来创建新的代码、向编译器输出信息、获取其他工具类等;

javax.lang.model.ElementKind 定义了 18 类 Element,包含 Java 代码中可能出现的全部元素,如包(Package)、枚举(Enum)、类(Class)、注解(AnnotationType)、接口(Interface)、枚举值(EnumConstant)、字段(Field)、参数(Parameter)、本地变量(LocalVariable)、异常(ExceptionnParameter)、方法(Method)、构造函数(Constructor)、静态语句块(StaticInit,即 static{} 块)、实例语句块(InstanceInit,即 {} 块)、参数化类型(TypeParameter,泛型尖括号内的类型)、资源变量(ResourceVariable,try-resource 中定义的变量)、模块(Module)、未定义的其他语法树节点(Other);

  • @SupportedAnnotationTypes,代表这个注解处理器对哪些注解感兴趣;
  • @SuppertedSourceVersion,表示这个注解处理器可以处理哪些版本的 Java 代码;

注解处理器 NameCheckProcessor


/*** "*" 表示支持所有 Annotations* 只支持 JDK 8 的 Java 代码** @author Aurelius Shu* @since 2023-02-19*/
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class NameCheckProcessor extends AbstractProcessor {private NameChecker nameChecker;/*** 初始化名称检查插件*/@Overridepublic 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


/*** 程序名称规范的编译器插件* 如果程序命名不合规范,将会输出一个编译器的 WARNING 信息** @author Aurelius Shu* @since 2023-02-19*/
public class NameChecker {private final Messager messager;NameCheckScanner nameCheckScanner = new NameCheckScanner();NameChecker(ProcessingEnvironment processsingEnv) {this.messager = processsingEnv.getMessager();}/*** 对Java程序命名进行检查,根据《Java语言规范》第三版第 6.8 节的要求,Java程序命名应当符合下列格式: * 类或接口:符合驼式命名法,首字母大写。* 方法:符合驼式命名法,首字母小写。* 字段:* 类、实例变量: 符合驼式命名法,首字母小写。* 常量: 要求全部大写。*/public void checkNames(Element element) {nameCheckScanner.scan(element);}/*** 名称检查器实现类,继承了 JDK 8 中新提供的ElementScanner8<br> * 将会以 Visitor 模式访问抽象语法树中的元素*/private class NameCheckScanner extends ElementScanner8<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() == METHOD) {Name name = e.getSimpleName();if (name.contentEquals(e.getEnclosingElement().getSimpleName())) {messager.printMessage(WARNING, "一个普通方法 “" + name + "”不应当与类名重复,避免与构造函数产生混淆", e);}checkCamelCase(e, false);}super.visitExecutable(e, p);return null;}/*** 检查变量命名是否合法*/@Overridepublic Void visitVariable(VariableElement e, Void p) {// 如果这个Variable是枚举或常量,则按大写命名检查,否则按照驼式命名法规则检查if (e.getKind() == ENUM_CONSTANT || e.getConstantValue() != null || heuristicallyConstant(e))checkAllCaps(e);else checkCamelCase(e, false);return null;}/*** 判断一个变量是否是常量*/private boolean heuristicallyConstant(VariableElement e) {if (e.getEnclosingElement().getKind() == INTERFACE) return true;else if (e.getKind() == FIELD && e.getModifiers().containsAll(EnumSet.of(PUBLIC, STATIC, FINAL)))return true;else {return false;}}/*** 检查传入的 Element 是否符合驼式命名法,如果不符合,则输出警告信息*/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(WARNING, "名称“" + name + "”应当以小写字母开头", e);return;}} else if (Character.isLowerCase(firstCodePoint)) {if (initialCaps) {messager.printMessage(WARNING, "名称“" + name + "”应当以大写字母开头", e);return;}} else {conventional = 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;} else previousUpper = false;if (!conventional)messager.printMessage(WARNING, "名称“" + name + "”应当符合驼式命名法(Camel Case Names)", e);}/*** 大写命名检查,要求第一个字母必须是大写的英文字母,其余部分可以是下划线或大写字母*/private void checkAllCaps(Element 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 == (int) '_') {if (previousUnderscore) {conventional = false;break;}previousUnderscore = true;} else {previousUnderscore = false;if (!Character.isUpperCase(cp) && !Character.isDigit(cp)) {conventional = false;break;}}}}if (!conventional) {messager.printMessage(WARNING, "常量“" + name + "”应当全部以大写字母或下划线命名,并且以字母开头", e);}}}
}

NameChecker 通过继承 javax.lang.model.util.ElementScanner8NameCheckScanner 类,以 Visitor 模式实现对语法树的遍历;通过 checkCamelCase() 与 checkAllCaps() 实现驼峰命名法和全大写命名的检查;分别在 visitType()、visitVariable()、visitExecutable() 中对类、字段、方法进行检查;

3. 运行与测试

不符合规范的代码演示

public class BADLY_NAMED_CODE {enum colors {red, blue, green;}static final int _FORTY_TWO = 42;public static int NOT_A_CONSTANT = _FORTY_TWO;protected void BADLY_NAMED_CODE() {return;}public void NOTcamelCASEmethodNAME() {return;}
}

运行注解处理器

# 编译注解处理器,切换到 src/main/java 路径
javac edu/aurelius/jvm/compiler/NameChecker.java
javac edu/aurelius/jvm/compiler/NameCheckProcessor.java# 编译时运行注解处理器
javac -processor edu.aurelius.jvm.compiler.NameCheckProcessor edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java

检查效果

edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:7: warning: 名称“BADLY_NAMED_CODE”应当符合驼式命名法(Camel Case Names)
public class BADLY_NAMED_CODE {^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:8: warning: 名称“colors”应当以大写字母开头enum colors {^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:9: warning: 常量“red”应当全部以大写字母或下划线命名,并且以字母开头red, blue, green;^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:9: warning: 常量“blue”应当全部以大写字母或下划线命名,并且以字母开头red, blue, green;^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:9: warning: 常量“green”应当全部以大写字母或下划线命名,并且以字母开头red, blue, green;^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:12: warning: 常量“_FORTY_TWO”应当全部以大写字母或下划线命名,并且以字母开头static final int _FORTY_TWO = 42;^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:13: warning: 名称“NOT_A_CONSTANT”应当以小写字母开头public static int NOT_A_CONSTANT = _FORTY_TWO;^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:15: warning: 一个普通方法 “BADLY_NAMED_CODE”不应当与类名重复,避免与构造函数产生混淆protected void BADLY_NAMED_CODE() {^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:15: warning: 名称“BADLY_NAMED_CODE”应当以小写字母开头protected void BADLY_NAMED_CODE() {^
edu/aurelius/jvm/compiler/BADLY_NAMED_CODE.java:19: warning: 名称“NOTcamelCASEmethodNAME”应当以小写字母开头public void NOTcamelCASEmethodNAME() {^
10 warnings

-XprintRounds-XprintProcessorInfo 参数可以进一步跟踪注解处理器的运作详细信息;

4. 其他应用案例

  • 校验 Hibernate 标签的正确性(Hibernate Validator Annotation Processor);
  • 自动为字段生成 getter、setter 方法等辅助内容(Lombok,根据已有元素生成新的语法树元素);

上一篇:「JVM 编译优化」Java 语法糖(泛型、自动装箱/拆箱、条件编译)

PS:感谢每一位志同道合者的阅读,欢迎关注、评论、赞!


参考资料:

  • [1]《深入理解 Java 虚拟机》
http://www.yayakq.cn/news/637634/

相关文章:

  • 如何选择家居网站建设枣庄网络推广公司
  • 安徽省建设干校学校网站黑色网站欣赏
  • 直播网站源码免费网站建设新手指南
  • 手机版免费申请微网站建设部资质网站查询
  • dede自动生成网站地图个人网站 内容建设
  • 网站开发服务器资源怎么弄手机网站制作公司
  • 专门做广东11选5的网站网站建设 招标任务书
  • php企业中英文网站源码徐州哪有做网站的
  • 阿里网站域名指向怎么做做公司网站首页
  • 浙江网站建设公司思科网站建设配置站点dns服务
  • 做抖音风的网站学产品设计的可以找什么工作
  • 公司网站建设是哪个部门的事情正版电子商务网
  • 外国网站域名在哪查淘宝联盟网站建设源码
  • 公司网站建设需要显示什么html网页爱心代码
  • 网站建设公司济南广州网站建设新际
  • 天猫店买卖网站如何制作新型网站程序
  • 网站的设计与开发的图片平面设计素材网站知乎
  • 中国工商做年报网站网站服务费一年多少钱
  • 网站建设五行属什么手机百度
  • 申请收费网站空间wordpress 前台发布
  • 做网站用asp好吗济宁一建建设集团有限公司
  • 杨浦专业做网站找附近的装修公司
  • 个人网站建设与管理工作总结中国空间站成功对接
  • 家装公司建设网站泰安企业建站公司电话
  • 搜狗网站制作轮网站开发的重要性
  • 求手机网站小程序源码网网盘
  • 鞍山制作网站的公司个人养老保险怎么买
  • 如何选择网站项目滨州做网站多少钱
  • 商城建站系统源码joomla 网站模板
  • 政协网站 是政协信息化建设wordpress是是什么技术