当前位置: 首页 > 工具软件 > JavaPoet > 使用案例 >

javapoet

居晗日
2023-12-01

参考:

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)
}


//###################################################################################
//####
//####                                   九
//####
//###################################################################################
 类似资料:

相关阅读

相关文章

相关问答