接下来我们演示一下如何用 APT工具生成一个class文件,然后我们再说 Lombok是如何修改已存在的类中的属性的 。
定义注解【一文读懂Lombok原理】首先当然我们需要定义自己的注解了
@Retention(RetentionPolicy.SOURCE) // 注解只在源码中保留@Target(ElementType.TYPE) // 用于修饰类public @interface GeneratePrint {String value();}
Retention注解上面有一个属性value,它是 RetentionPolicy类型的枚举类,RetentionPolicy枚举类中有三个值 。
public enum RetentionPolicy {SOURCE,CLASS,RUNTIME}
- SOURCE修饰的注解:修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中
- CLASS修饰的注解:表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候
- RUNTIME修饰的注解:表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时 。所以它能够通过反射调用,所以正常运行时注解都是使用的这个参数
public enum ElementType {TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE} 定义注解处理器我们要定义注解处理器的话,那么就需要继承 AbstractProcessor类 。继承完以后基本的框架类型如下
@SupportedSourceVersion(SourceVersion.RELEASE_8)@SupportedAnnotationTypes("aboutjava.annotion.MyGetter")public class MyGetterProcessor extends AbstractProcessor {@Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);}@Overridepublic boolean process(Set<!--? extends TypeElement--> annotations, RoundEnvironment roundEnv) {return true;}} 我们可以看到在子类中上面有两个注解,注解描述如下
- @SupportedSourceVersion:表示所支持的Java版本
- @SupportedAnnotationTypes:表示该处理器要处理的注解
- init方法:主要是获得编译时期的一些环境信息
- process方法:在编译时,编译器执行的方法 。也就是我们写具体逻辑的地方
@Overridepublic boolean process(Set<!--? extends TypeElement--> annotations, RoundEnvironment roundEnv) {StringBuilder builder = new StringBuilder().Append("package aboutjava.annotion;nn").append("public class GeneratedClass {nn") // open class.append("tpublic String getMessage() {n") // open method.append("ttreturn "");// for each javax.lang.model.element.Element annotated with the CustomAnnotationfor (Element element : roundEnv.getElementsAnnotatedWith(MyGetter.class)) {String objectType = element.getSimpleName().toString();// this is appending to the return statementbuilder.append(objectType).append(" says hello!\n");}builder.append("";n") // end return.append("t}n") // close method.append("}n"); // close classtry { // write the fileJavaFileObject source = processingEnv.getFiler().createSourceFile("aboutjava.annotion.GeneratedClass");Writer writer = source.openWriter();writer.write(builder.toString());writer.flush();writer.close();} catch (IOException e) {// Note: calling e.printStackTrace() will print IO errors// that occur from the file already existing after its first run, this is normal}return true;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 一文搞懂HTTP协议的核心知识点
- 一文玩转dockerfile
- 个人交社保、单位交社保,差别到底在哪里?一文读懂
- 一文搞懂交换基础知识
- 一文读懂常用开源许可证
- 抽水马桶是如何工作的?一文看懂虹吸原理
- 一文讲弄懂什么是vlan、三层交换机、网关、子网掩码
- 一文教您如何实现持续集成服务器环境搭建
- 一文搞定MySQL性能调优
- 一文了解神经网络工作原理
