编译期注解之JavaPoet

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译期注解之JavaPoet

0x01 简单使用

使用之前要先引入这个库

compile 'com.squareup:javapoet:1.7.0'

javapoet是用来生成代码的,需要借助

常用类

使用javapoet前需要了解4个常用类

MethodSpec 代表一个构造函数或方法声明。

TypeSpec 代表一个类,接口,或者枚举声明。

FieldSpec 代表一个成员变量,一个字段声明。

JavaFile包含一个顶级类的Java文件。

国际惯例先自动生成一个helloWorld类

定义一个编译期注解

@Retention(RetentionPolicy.CLASS)

@Target(ElementType.TYPE)

public @interface clazz_hello {

String value();

}

然后看下helloworld的注解处理器

@AutoService(Processor.class)

public class HelloWorldProcess extends AbstractProcessor {

private Filer filer;

@Override

public synchronized void init(ProcessingEnvironment processingEnv) {

super.init(processingEnv);

filer = processingEnv.getFiler();

}

@Override

public boolean process(Set annotations, RoundEnvironment roundEnv) {

for (TypeElement element : annotations) {

if

(element.getQualifiedName().toString().equals(clazz_hello.class.getCanonicalName())) {

MethodSpec main = MethodSpec.methodBuilder("main")

.addModifiers(Modifier.PUBLIC, Modifier.STATIC)

.returns(void.class)

.addParameter(String[].class, "args")

.addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")

.build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")

.addModifiers(Modifier.PUBLIC, Modifier.FINAL)

.addMethod(main)

.build();

try {

JavaFile javaFile = JavaFile.builder("com.xsf", helloWorld)

.addFileComment(" This codes are generated automatically. Do not modify!")

.build();

javaFile.writeTo(filer);

} catch (IOException e) {

e.printStackTrace();

}

}

}

return true;

}

@Override

public Set getSupportedAnnotationTypes() {

Set annotations = new LinkedHashSet<>();

annotations.add(clazz_hello.class.getCanonicalName());

return annotations;

}

@Override

public SourceVersion getSupportedSourceVersion() {

return testSupported();

}

}

这样就会在app-build-source-apt-debug-com.xsf文件夹下生成这个文件

0x02 使用进阶

方法&控制流:

添加方法addcode 和addstatement

对与无需类引入的极简代码可以直接使用addCode

MethodSpec main = MethodSpec.methodBuilder("main")

.addCode(""

+ "int total = 0;\n"

+ "for (int i = 0; i < 10; i++) {\n"

+ " total += i;\n"

+ "}\n")

.build();

生成的是

void main() {

int total = 0;

for (int i = 0; i < 10; i++) {

total += i;

}

}

要是需要import的方法,如上面的.addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") 就需要使用.addStatement来声明

更优雅的流控制

beginControlFlow 流开启

addStatement 处理语句

endControlFlow()流结束

如上面的用流改写就是

MethodSpec main = MethodSpec.methodBuilder("main")

.addStatement("int total = 0")

.beginControlFlow("for (int i = 0; i < 10; i++)")

.addStatement("total += i")

.endControlFlow()

.build();

占位符

javapoet里面提供了占位符来帮助我们更好地生成代码

$L 字面常量(Literals)

private MethodSpec computeRange(String name, int from, int to, String op) {

return MethodSpec.methodBuilder(name)

.returns(int.class)

相关文档
最新文档