JavaPoet是提供于自动生成java文件的构建工具类框架,使用该框架可以方便根据我们所注解的内容在编译时进行代码构建。
以下为该框架项目地址
https://github.com/square/javapoet
类 | 说明 | 备注 |
---|---|---|
MethodSpec | 方法构造 | |
TypeSpec | 类、接口、枚举构造 | |
FieldSpec | 成员变量、字段构造 | |
JavaFile | 顶级Java文件 | |
ParameterSpec | 参数构造 | |
AnnotationSpec | 注解构造 |
例子
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();
JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build();
javaFile.writeTo(System.out);
MethodSpec
方法 | 说明 | 备注 |
---|---|---|
returns | 返回值 | |
addStatement | 添加语句 | |
beginControlFlow | 控制语句(if、while、for) | |
endControlFlow | 结束控制语句 |
addStatement占位符
占位符 | 作用 | 备注 |
---|---|---|
$L | 万用占位符 | |
$S | 字符串占位符 | |
$T | 内置类型映射支持,会自动 import 声明 | 可以更方便的结合ClassName使用 |
$N | 当引用一个通过名字生成的声明时,可以用当前这个占位符进行占位 | |
$T结合ClassName的使用
在什么对象时可以通过ClassName进行声明
ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard");
ClassName list = ClassName.get("java.util", "List");
ClassName arrayList = ClassName.get("java.util", "ArrayList");
TypeName listOfHoverboards = ParameterizedTypeName.get(list, hoverboard);
MethodSpec beyond = MethodSpec.methodBuilder("beyond")
.returns(listOfHoverboards)
.addStatement("$T result = new $T<>()", listOfHoverboards, arrayList)
.addStatement("result.add(new $T())", hoverboard)
.addStatement("result.add(new $T())", hoverboard)
.addStatement("result.add(new $T())", hoverboard)
.addStatement("return result")
.build();
占位符顺序替换
CodeBlock.builder().add("I ate $2L $1L", "tacos", 3)
通过在占位符前添加对应占位符位置改变填充值的位置
指定标签替换
占位符支持指定标签Key后用Map替换对应的值
Map map = new LinkedHashMap<>();
map.put("food", "tacos");
map.put("count", 3);
CodeBlock.builder().addNamed("I ate $count:L $food:L", map)
控制流(if、while、for)
一般情况下我们可以这样添加控制语句:
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;
}
}
MethodSpec提供beginControlFlow和endControlFlow控制流程事务。
MethodSpec main = MethodSpec.methodBuilder("main")
.addStatement("int total = 0")
.beginControlFlow("for (int i = 0; i < 10; i++)")
.addStatement("total += i")
.endControlFlow()
.build();