JavaPoet的简单了解
JavaPoet是一个用来生成.java源文件的Java第三方库,在ButterKnife注解库中首次见到了这个工具,当做如注解或者数据库模式、协议格式等事情时,生成源文件就比较有用处。
参考博客地址 http://www.jianshu.com/p/95f12f72f69a
官方github地址 https://github.com/square/javapoet
1.配置过程
- 直接下载jar包 http://central.maven.org/maven2/com/squareup/javapoet/
- 配置gradle
compile 'com.squareup:javapoet:1.9.0'
2.使用方法
javaPoet中常用的几个类
MethodSpec 代表一个构造函数或方法声明
TypeSpec 代表一个类,接口,或者枚举声明
FieldSpec 代表一个成员变量,一个字段声明
JavaFile包含一个顶级类的Java文件
2.1首先写一个产生helloworld的源文件
public class AutoGenerateHelloWorldDemo {
public static void main(String[] args) throws IOException {
generateHelloWorld();
}
private static void generateHelloWorld() throws IOException {
//新建一个方法
MethodSpec main = MethodSpec.methodBuilder("main")
.addModifiers(Modifier.PUBLIC,Modifier.STATIC) //声明方法为public static
.addParameter(String[].class , "args") //声明方法的参数
.addStatement("$T.out.println($S)",System.class,"hello world") //声明方法的代码
.build();
//新建一个类
TypeSpec typeSpec = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC,Modifier.FINAL)
.addMethod(main) //加入上面声明的方法
.build();
//新建一个java文件
JavaFile javaFile = JavaFile.builder("",typeSpec) //加入上面声明的类
.build();
javaFile.writeTo(System.out);
}
}
输出结果
import java.lang.String;
import java.lang.System; //这里自动导入了System是因为在方法中加入代码时使用了$T
public final class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
}
}
总结一下大致使用流程:
1.声明方法,可以加入各种修饰符等
2.声明一个类,把上面声明的方法加入到类中去
3.声明一个JavaFile文件,把上面的类加入文件中
2.2产生一个流程控制的初步代码
private static void generateFlow(){
MethodSpec way = MethodSpec.methodBuilder("loopadd")
.addStatement("int result = 0")
.beginControlFlow("for (int i = 0 ; i < 10 ;i++)")
.addStatement("result += i")
.endControlFlow()
.addStatement("return result")
.returns(int.class)
.build();
System.out.println(way); //MethodSpec重写了toString()方法,可以直接打印查看
}
输出结果
int loopadd() {
int result = 0;
for (int i = 0 ; i < 10 ;i++) {
result += i;
}
return result;
}
产生一个流程控制的改进代码,使用了占位符
介绍占位符
- $L Literals,翻译为字面量,官方教程中代替int
- $S Strings,String类型的字符串
- $T Types,对应一个类,会自动导入类
- $N Names 我们自己生成的方法名或者变量名
private static MethodSpec generateRange(String name, int from , int to , String op){
return MethodSpec.methodBuilder(name)
.returns(int.class)
.addStatement("int result = 0")
.beginControlFlow("for (int i = $L;i < $L;i++)",from , to)
.addStatement("result $L= i",op)
.endControlFlow()
.addStatement("return result")
.build();
}
3.产生字段
private static void generateFields(){
//声明一个字段
FieldSpec android = FieldSpec.builder(String.class , "android")
.addModifiers(Modifier.PRIVATE , Modifier.FINAL)
.build();
TypeSpec bean = TypeSpec.classBuilder("Android")
.addModifiers(Modifier.PUBLIC)
.addField(android)
.addField(int.class ,"version",Modifier.PRIVATE)
.build();
System.out.println(bean);
}
总结,javapoet还有更加具体的教程可以查看官网说明,我们使用javapoet产生重复的代码,可以使用编译时注解+javaPoet来实现编译期间动态生成代码,Butterknife用的APT(Annotation Processing Tool)编译时解析技术。