简单介绍 Java 中的编译时注解

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了简单介绍 Java 中的编译时注解脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

1. 前言

上一篇 主要介绍了什么是 注解 (Annotation) 以及如何读取 运行时注解 中的数据, 同时用注解实现了简单ORM 功能. 这次介绍另一部分: 如何读取 编译时注解 ( Retentionpolicy.SOURCE )

2. 作用

编译时注解可以用来动态生成代码. 使用 SOURCE 类型注解的代码会在编译时被解析, 生成新的 java 文件, 然后和原来java 文件一起编译成字节码. 由于不使用反射功能, 编译时注解不会拖累性能, 因而被许多框架使用, 比如 Butter Knife, Dragger2 等.

3. 例子

1. 代码

还是从简单的例子开始看. 这里要做的是生成一个 java 类, 其拥有一个打印注解信息的方法.
先定义一个注解

package apt; ...... @Retention(RetentionPolicy.SOURCE) // 注解只在码中保留 @Target(ElementTyPE.TYPE) // 用于修饰类 public @interface Hello {     String name() default ""; }

使用注解的类

package apt; @Hello(name = "world") public class player { }

不使用注解的类, 用于对比

package apt; public class Ignored { }

上一篇说过, 注解没有行为, 只有数据, 需要对应的处理器才能发挥作用. javac 提供了解析编译时注解的注解处理器 ( Annotation PRocessor ). 对于自定义的注解, 需要手动实现它的注解处理器.下面来看一个简单的注解处理器实现.

package apt;  import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.JavaFileObject; import java.io.IOException; import java.io.Writer; import java.util.Set;  /**  * Created by away on 2017/6/12.  */ @SupportedSourceVersion(SourceVersion.RELEASE_8) // 源码级别, 这里的环境是 jdk 1.8 @SupportedAnnotationTypes("apt.Hello") // 处理的注解类型, 这里需要处理的是 apt 包下的 Hello 注解(这里也可以不用注解, 改成重写父类中对应的两个方法) public class HelloProcessor extends AbstractProcessor {      // 计数器, 用于计算 process() 方法运行了几次     private int count = 1;      // 用于写文件     private Filer filer;      @Override     public synchronized void init(ProcessingEnvironment processingEnv) {         super.init(processingEnv);         filer = processingEnv.getFiler();     }      // 处理编译时注解的方法     @Override     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {         System.out.println("start process, count = " + count++);         // 获得所有类         Set<? extends Element> rootElements = roundEnv.getRootElements();         System.out.println("all class:");          for (Element rootElement : rootElements) {             System.out.println("  " + rootElement.getSimpleName());         }          // 获得有注解的元素, 这里 Hello 只能修饰类, 所以只有类         Set<? extends Element> elementsAnnotatedWith = roundEnv.getElementsAnnotatedWith(Hello.class);         System.out.println("annotated class:");         for (Element element : elementsAnnotatedWith) {             String className = element.getSimpleName().toString();             System.out.println("  " + className);              String output = element.getAnnotation(Hello.class).name();             // 产生的动态类的名字             String newClassName = className + "_New";             // 写 java 文件             createFile(newClassName, output);         }         return true;     }      private void createFile(String className, String output) {         StringBuilder cls = new StringBuilder();         cls.append("package apt;nnpublic class ")                 .append(className)                 .append(" {n  public static void main(String[] args) {n")                 .append("    System.out.println("")

脚本宝典总结

以上是脚本宝典为你收集整理的简单介绍 Java 中的编译时注解全部内容,希望文章能够帮你解决简单介绍 Java 中的编译时注解所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。