更为方便的书写编译时注解——javapoet
2017-02-27 15:08
417 查看
简介
编译时注解以其在保有注解低耦合等传统特点的同时又能兼顾性能被开发人员所热爱,但是,在写编译过程动态生成代码文件时的琐碎工作让人头疼,square公司推出的javapoet则完美的解决了这一问题,让动态生成代码不在难写。这里介绍下这个框架。
一、注解部分
这里不在对注解部分做详细的描述,网上有很多关于java注解的资料,再此只对在做注解时运用到的两个注解和一个抽象类进行大概的介绍。
写注解时用到的两个注解Retention和Target,其中Retention注解的属性值为RetentionPolicy类型,而RetentionPolicy为枚举类:
SOURCE:停留在代码中,不会参与编译;
ClASS:会被记录在Class文件中,但不参与运行时调用;
RUNTIME:运行时可用。
Target注解的属性值是ElementType,作用是规定被注解对象的具体类型
还有一个编译时所需要的抽象类AbstractProcessor,想要了解的更多可以看下鸿洋大神的博客http://blog.csdn.net/lmj623565791/article/details/43452969
二、Javapoet部分
进入重点,首先明白在一个.java文件的构造中,包含四大元素:成员变量(Field)、方法(method)、类或接口(Type)、文件(File)。在Javapoet中,对这四大元素有对应的操作类:
FieldSpec: 负责控制成员变量及常量的声明
MethodSpec: 负责生成类中的方法
TypeSpec: 负责类或者接口的部分生成
JavaFile: 负责在根据制定的位置进行文件的输出,以及进行必要的类包导入
先上一段经典的helloworld纪念逝去的青春:
可以注意到,除了JavaFile中,都对Modifier进行了使用,这个类的作用就是设置声明、方法、以及类的修饰语关键字,它本身是一个枚举类。
addStatement方法可以直接写入代码行,需要注意的时不用加”;”
再细致点可以发现,输出语句中使用了$S、$L、$N、$T四种占位符
$T:表示需要调用类或者接口;
$L:表示要对应的常量
$S:表示对应的字符串(和$L的区别在于,字符串进入代码中仍为字符串,而$L则不会加"")
$N:表示对应(FieldSpec、MethodSpec、TypeSpec)要注入的变量常量、方法、类的名字。
需要注意的是,在Javapoet中会帮你自动引入包,如果想要手动引入自己需要的包,还可以通过JavaFile.Builder生成的对象调用addStaticImort(
)方法。
在JavaPoet中还有更多好用的方法,比如beginControlFlow和endControlFlow等,在github上可以直接看到,就不在一一例举了
github地址:https://github.com/square/javapoet
编译时注解以其在保有注解低耦合等传统特点的同时又能兼顾性能被开发人员所热爱,但是,在写编译过程动态生成代码文件时的琐碎工作让人头疼,square公司推出的javapoet则完美的解决了这一问题,让动态生成代码不在难写。这里介绍下这个框架。
一、注解部分
这里不在对注解部分做详细的描述,网上有很多关于java注解的资料,再此只对在做注解时运用到的两个注解和一个抽象类进行大概的介绍。
写注解时用到的两个注解Retention和Target,其中Retention注解的属性值为RetentionPolicy类型,而RetentionPolicy为枚举类:
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }其中的三个枚举类型代表这注解的运行范围
SOURCE:停留在代码中,不会参与编译;
ClASS:会被记录在Class文件中,但不参与运行时调用;
RUNTIME:运行时可用。
Target注解的属性值是ElementType,作用是规定被注解对象的具体类型
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE }
还有一个编译时所需要的抽象类AbstractProcessor,想要了解的更多可以看下鸿洋大神的博客http://blog.csdn.net/lmj623565791/article/details/43452969
二、Javapoet部分
进入重点,首先明白在一个.java文件的构造中,包含四大元素:成员变量(Field)、方法(method)、类或接口(Type)、文件(File)。在Javapoet中,对这四大元素有对应的操作类:
FieldSpec: 负责控制成员变量及常量的声明
MethodSpec: 负责生成类中的方法
TypeSpec: 负责类或者接口的部分生成
JavaFile: 负责在根据制定的位置进行文件的输出,以及进行必要的类包导入
先上一段经典的helloworld纪念逝去的青春:
FieldSpec fieldSpec = FieldSpec.builder(String.class,"world") .addModifiers(Modifier.PRIVATE,Modifier.STATIC,Modifier.FINAL) .initializer("$S","World") .build(); MethodSpec methodSpec = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(void.class) .addParameter(String[].class, "args") .addStatement("$T.out.println($S+$N+\"$L\")", System.class,"Hello",fieldSpec,"!") .build(); TypeSpec typeSpec = TypeSpec.classBuilder("HelloWorld") .addModifiers(Modifier.PUBLIC) .addField(fieldSpec) .addMethod(methodSpec) .build(); JavaFile javaFile = JavaFile.builder("com.example",typeSpec) .build(); javaFile.writeTo(System.out);生成代码如下:
可以注意到,除了JavaFile中,都对Modifier进行了使用,这个类的作用就是设置声明、方法、以及类的修饰语关键字,它本身是一个枚举类。
addStatement方法可以直接写入代码行,需要注意的时不用加”;”
再细致点可以发现,输出语句中使用了$S、$L、$N、$T四种占位符
$T:表示需要调用类或者接口;
$L:表示要对应的常量
$S:表示对应的字符串(和$L的区别在于,字符串进入代码中仍为字符串,而$L则不会加"")
$N:表示对应(FieldSpec、MethodSpec、TypeSpec)要注入的变量常量、方法、类的名字。
需要注意的是,在Javapoet中会帮你自动引入包,如果想要手动引入自己需要的包,还可以通过JavaFile.Builder生成的对象调用addStaticImort(
)方法。
在JavaPoet中还有更多好用的方法,比如beginControlFlow和endControlFlow等,在github上可以直接看到,就不在一一例举了
github地址:https://github.com/square/javapoet
相关文章推荐
- 自定义注解之编译时注解(RetentionPolicy.CLASS)(二)——JavaPoet
- 自定义注解之编译时注解(RetentionPolicy.CLASS)(二)——JavaPoet
- java-脚本-编译-注解
- Java编译时注解自动生成代码
- 能够使开发和调试更为方便的java日志框架
- Java注解处理器学习之编译时处理的注解详析
- java10下编译lombok注解代码分享
- Android(Java)编译时注解修改代码
- eclipse编译项目:Java @Override 注解报错的解决方法
- 用notepad++书写java,编译java程序是出现:错误: 编码GBK的不可映射字符问题的解决
- 关于java编译时注解你需要知道的二三事。解除你的顾虑!
- 编译期注解之JavaPoet
- 1.Android注解-编译时生成代码 APT(Annotation Processing Tool ) Poet 说明
- java10下编译lombok注解的代码
- 利用编译时注解生成Java源代码
- 编译时注解,继承AbstractProcessor自动生成java文件。
- 利用编译时注解生成Java源代码
- 一个java简单类的书写,闲时可以拿来练手(要求一次性编译通过)
- (2.1.19.3)深入理解Java:注解(Annotation)–编译时注解的处理
- [zt]Java编译环境的构建