参考:
javapoet官网
kotlinpoet官网
JavaPoet的基本使用
常用类
- MethodSpec 代表一个构造函数或方法声明
- TypeSpec 代表一个类,接口,或者枚举声明
- FieldSpec 代表一个成员变量,一个字段声明
- JavaFile 包含一个顶级类的Java文件
- ParameterSpec 用来创建参数
- AnnotationSpec 用来创建注解
- TypeName 类型,如在添加返回值类型是使用 TypeName.VOID
- ClassName 用来包装一个类
占位符
- $L 参数
- S 字 符 串 的 模 板 , 将 指 定 的 字 符 串 替 换 到 S 字符串的模板,将指定的字符串替换到 S字符串的模板,将指定的字符串替换到S的地方
- $N $N在JavaPoet中代指的是一个名称,例如调用的方法名称,变量名称,这一类存在意思的名称
- $T $T 在JavaPoet代指的是TypeName,该模板主要将Class抽象出来,用传入的TypeName指向的Class来代替
导入:
implementation 'com.squareup:javapoet:1.12.1'
测试
注意: 新建Java module 才可使用 javax.lang.model.element.Modifier
fun main() {
println("----------------------start--------------------------")
println()
// test1()
// test2()
// test3()
test4()
println()
println("----------------------end--------------------------")
}
//###################################################################################
//####
//#### 一
//####
//###################################################################################
fun test1() {
val main = MethodSpec.methodBuilder("main")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(Void.TYPE)
.addParameter(Array<String>::class.java, "args")
.addStatement("\$T.out.println(\$S)", System::class.java, "Hello, JavaPoet!")
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(main)
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
//###################################################################################
//####
//#### 二
//####
//###################################################################################
fun test2() {
val main = MethodSpec.methodBuilder("main")
.addCode(
""
+ "int total = 0;\n"
+ "for (int i = 0; i < 10; i++) {\n"
+ " total += i;\n"
+ "}\n"
)
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(main)
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
//###################################################################################
//####
//#### 三
//####
//###################################################################################
/**
* addStatement() 负责分号和换行,
* beginControlFlow() + endControlFlow() 需要一起使用,提供换行符和缩进。
*/
fun test3() {
val main = MethodSpec.methodBuilder("main")
.addStatement("int total = 1")
.beginControlFlow("for (int i = 0; i < 10; i++)")
.addStatement("total += i")
.endControlFlow()
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(main)
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
//###################################################################################
//####
//#### 四
//####
//###################################################################################
private fun computeRange(
name: String,
from: Int,
to: Int,
op: String
): MethodSpec? {
return MethodSpec.methodBuilder(name)
.returns(Int::class.javaPrimitiveType)
.addStatement("int result = 2")
.beginControlFlow("for (int i = $from; i < $to; i++)")
.addStatement("result = result $op i")
.endControlFlow()
.addStatement("return result")
.build()
}
/**
* 将方法的生成提成单独的方法computeRange
*/
fun test4() {
val computeRange = computeRange("multiply10to20", 10, 20, "*")
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(computeRange)
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
//###################################################################################
//####
//#### 五
//####
//###################################################################################
//$L for Literals
//
//字符串连接的方法beginControlFlow() 和 addStatement是分散开的,操作较多。
//针对这个问题, JavaPoet 提供了一个语法但是有违String.format()语法.
// 通过 $L 来接受一个 literal 值。 这有点像 Formatter’s %s:
private fun computeRange5(
name: String,
from: Int,
to: Int,
op: String
): MethodSpec? {
return MethodSpec.methodBuilder(name)
.returns(Int::class.javaPrimitiveType)
.addStatement("int result = 0")
.beginControlFlow("for (int i = \$L; i < \$L; i++)", from, to)
.addStatement("result = result \$L i", op)
.endControlFlow()
.addStatement("return result")
.build()
}
/**
* 将方法的生成提成单独的方法computeRange
*/
fun test5() {
val computeRange5 = computeRange5("multiply10to20", 10, 20, "*")
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(computeRange5)
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
//###################################################################################
//####
//#### 六
//####
//###################################################################################
//$S for Strings
//
//当输出的代码包含字符串的时候, 可以使用 $S 表示一个 string。
//下面的代码包含三个方法,每个方法返回自己的名字:
fun test6() {
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(
Modifier.PUBLIC,
Modifier.FINAL
)
.addMethod(whatsMyName("slimShady"))
.addMethod(whatsMyName("eminem"))
.addMethod(whatsMyName("marshallMathers"))
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
private fun whatsMyName(name: String): MethodSpec? {
return MethodSpec.methodBuilder(name)
.returns(String::class.java)
.addStatement("return \$S", name)
.build()
}
//###################################################################################
//####
//#### 七
//####
//###################################################################################
//$T for Types
//
//使用Java内置的类型会使代码比较容易理解。
// JavaPoet极大的支持这些类型,通过 $T 进行映射,会自动import声明。
fun test7(){
val today: MethodSpec = MethodSpec.methodBuilder("today")
.returns(Date::class.java)
.addStatement("return new \$T()", Date::class.java)
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(
Modifier.PUBLIC,
Modifier.FINAL
)
.addMethod(today)
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
//###################################################################################
//####
//#### 八
//####
//###################################################################################
fun test9(){
val flux = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
.addParameter(String::class.java, "greeting")
.addStatement("this.\$N = \$N", "greeting", "greeting")
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC)
.addField(
String::class.java,
"greeting",
Modifier.PRIVATE,
Modifier.FINAL
)
.addMethod(flux)
.build()
val javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build()
javaFile.writeTo(System.out)
}
//###################################################################################
//####
//#### 九
//####
//###################################################################################