前言
javapoet是square公司旗下的一款开源项目,旨在用java api 生成.java源代码文件,就连大名鼎鼎的Butterknify也用到了这个开源库,英语好的同学可以直接移步该项目的gayhub地址。
举个例子
假如要生成类似这样的一个文件
package com.simple;
import java.lang.String;
import java.lang.System;
public final class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello JavaPoet")}
}
那我们的代码将是这样
public class JevePoet_demo {
public static void main(String[] args) {
generateMain();
}
public static void generateMain() {
//生成方法
MethodSpec main = MethodSpec
//生成方法名为main
.methodBuilder("main")
//方法修饰为public,static
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
//返回值为void
.returns(TypeName.VOID)
//添加参数
.addParameter(String[].class, "args")
//$T,$s类似占位符
.addCode("$T.out.println($S)", System.class, "Hello JavaPoet")
//生成
.build();
//生成类,接口或枚举
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
//类修饰为public,static
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
//将方法添加进去
.addMethod(main)
.build();
String packageName = "com.simple";
//生成java文件
JavaFile javaFile = JavaFile.builder(packageName, helloWorld)
.build();
try {
//输出java文件的内容
javaFile.writeTo(System.out);
//也可以直接输出文件查看
// File absoluteFile = new File("").getAbsoluteFile();
// javaFile.writeTo(absoluteFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
注释已经写的很明白了,我们再看看几个常用的类
- MethodSpec 声明生成一个构造函数或方法
- TypeSpec 声明生成类,接口或枚举
- FieldSpec 声明生成一个成员变量或字段
- JavaFile 包含顶部类的java文件,生成代码就看它啦
- $L 数值的占位符
- $S 字符的占位符
- $T 引用类型的占位符
- $N 名称的占位符(指根据名称生成另一个声明)
上面代码需要导入javapoet的包
compile ‘com.squareup:javapoet:1.7.0’
并且要用javapoet只能是java构建的项目,不能是android构件的项目。否则就会爆一些很奇怪的错误。
接下来我们输出一个for循环看看,只把关键部分换一换
.addCode(""
+ "int total = 0;\n"
+ "for (int i = 0; i < 10; i++) {\n"
+ " total += i;\n"
+ "}\n")
生成后的代码
public static void main(String[] args) {
int total = 0;
for (int i = 0; i < 10; i++) {
total += i;
}
}
看着好像也没有什么问题,但是总觉得这样用字符串拼接代码如果出问题了很难排查,所以当然有更好的办法。
MethodSpec main = MethodSpec.methodBuilder("main")
//和addCode类似,但是自带换行和分号
.addStatement("int total = 0")
//添加一个"{\n"
.beginControlFlow("for (int i = 0; i < 10; i++)")
.addStatement("total += i")
//添加一个"}\n"
.endControlFlow()
.build();
总结
上面只是简单的介绍了javapoet的用法,具体更多的内容还是要去github看。javapoet如其名一样,就像一个诗人,你可以通过它生成代码,无需编写样板,同时也保持真实性单一来源的元数据。在编译时注解处理和元数据文件处理(例如,数据库架构,协议格式)特别有用!