脚本宝典收集整理的这篇文章主要介绍了简单介绍 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,请注明来意。