%T 用于类型¶
KotlinPoet 内置了对类型的丰富支持,包括自动生成 import
语句。只需使用 %T
来引用类型即可。
val today = FunSpec.builder("today")
.returns(Date::class)
.addStatement("return %T()", Date::class)
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addFunction(today)
.build()
val kotlinFile = FileSpec.builder("com.example.helloworld", "HelloWorld")
.addType(helloWorld)
.build()
kotlinFile.writeTo(System.out)
这将生成以下 .kt
文件,其中包含必要的 import
语句
package com.example.helloworld
import java.util.Date
class HelloWorld {
fun today(): Date = Date()
}
我们将 Date::class
传递进去,以引用一个恰好在我们生成代码时可用的类。但这并非必须如此。这里有一个类似的例子,但它引用了一个(尚)不存在的类
val hoverboard = ClassName("com.mattel", "Hoverboard")
val tomorrow = FunSpec.builder("tomorrow")
.returns(hoverboard)
.addStatement("return %T()", hoverboard)
.build()
那个尚不存在的类同样会被导入
package com.example.helloworld
import com.mattel.Hoverboard
class HelloWorld {
fun tomorrow(): Hoverboard = Hoverboard()
}
ClassName
类型非常重要,在使用 KotlinPoet 时你会经常用到它。它可以识别任何声明过的类。声明类型只是 Kotlin 丰富类型系统的开端:我们还有数组、参数化类型、通配符类型、lambda 类型和类型变量。KotlinPoet 为构建所有这些类型提供了相应的类
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.STAR
val hoverboard = ClassName("com.mattel", "Hoverboard")
val list = ClassName("kotlin.collections", "List")
val arrayList = ClassName("kotlin.collections", "ArrayList")
val listOfHoverboards = list.parameterizedBy(hoverboard)
val arrayListOfHoverboards = arrayList.parameterizedBy(hoverboard)
val thing = ClassName("com.misc", "Thing")
val array = ClassName("kotlin", "Array")
val producerArrayOfThings = array.parameterizedBy(WildcardTypeName.producerOf(thing))
val beyond = FunSpec.builder("beyond")
.returns(listOfHoverboards)
.addStatement("val result = %T()", arrayListOfHoverboards)
.addStatement("result += %T()", hoverboard)
.addStatement("result += %T()", hoverboard)
.addStatement("result += %T()", hoverboard)
.addStatement("return result")
.build()
val printThings = FunSpec.builder("printThings")
.addParameter("things", producerArrayOfThings)
.addStatement("println(things)")
.build()
val printKClass = FunSpec.builder("printKClass")
.addParameter("kClass", KClass::class.asClassName().parameterizedBy(STAR))
.addStatement("println(kClass)")
.build()
STAR
在 KotlinPoet 中表示为 *
。你可以在 KDoc 中找到更多信息。
KotlinPoet 会分解每种类型,并在可能的情况下导入其组件。
package com.example.helloworld
import com.mattel.Hoverboard
import com.misc.Thing
import kotlin.Array
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.reflect.KClass
class HelloWorld {
fun beyond(): List<Hoverboard> {
val result = ArrayList<Hoverboard>()
result += Hoverboard()
result += Hoverboard()
result += Hoverboard()
return result
}
fun printThings(things: Array<out Thing>) {
println(things)
}
fun printKClass(kClass: KClass<*>) {
println(kClass)
}
}
可空类型¶
KotlinPoet 支持可空类型。要将 TypeName
转换为其对应的可空类型,请使用 copy()
方法,并将 nullable
参数设置为 true
val java = PropertySpec.builder("java", String::class.asTypeName().copy(nullable = true))
.mutable()
.addModifiers(KModifier.PRIVATE)
.initializer("null")
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addProperty(java)
.addProperty("kotlin", String::class, KModifier.PRIVATE)
.build()
生成
class HelloWorld {
private var java: String? = null
private val kotlin: String
}