Kotlin 可以将内联函数中的泛型进行实化,在声明泛型的地方加上reified
关键字来表示该泛型要进行实化。
inline fun <reified T> getGenericType(){}
上述函数中的泛型 T 就是一个可以被实化的泛型,那么借助泛型实化,可以实现怎样的效果呢?
inline fun <reified T> getGenericType() = T::class.java
fun main() {
val strType = getGenericType<String>()
val intType = getGenericType<Int>()
// class java.lang.String
println(strType)
// class java.lang.Integer
println(intType)
}
我们使用 T::class.java
来返回了 T 的具体类型,那么在我们调用的时候,传入什么类型实参,就能获取到相应的具体类型了。
泛型实化的应用
val intent = Intent(context, MainActivity::class.java)
context.startActivity(intent)
上述代码是我们平常跳转一个 Activity 时常写的代码,每次我们都需要 MainActivity::class.java
这样的语法来传入一个 class,现在我们就使用泛型实化来简化它们。
inline fun <reified T> startActivity(context: Context) {
val intent = Intent(context, T::class.java)
context.startActivity(intent)
}
上面我们定义了一个内联函数,并指明函数的泛型可以实化,那么我们就可以获取到泛型的类型从而传递给 Intent 来使用,下面看看我们怎么调用这个函数。
startActivity<MainActivity>(context)
这样,我们将需要跳转的 Activity 指定为函数的泛型实参,那么 Kotlin 就能识别出相应的泛型的实际类型,从而启动相应的 Activity。
下面我们继续来优化这个方法,如果我们要给下一个 Activity 传递参数,那么可以使用高阶函数来方便的给 Intent 传递参数。
inline fun <reified T> startActivity(context: Context, block: Intent.() -> Unit) {
val intent = Intent(context, T::class.java)
intent.block()
context.startActivity(intent)
}
上述代码中,我们给 startActivity() 函数添加了一个函数类型参数,并且这个函数类型是定义在 Intent 类当中的,并且会持有 Intent 的上下文,在创建 Intent 实例之后,就可以调用这个函数类型参数。然后我们调用 startActivity() 函数的时候就可以在 Lambda 表达式中为 Intent 传递参数了。
startActivity<MainActivity>(context) {
putExtra("name","LK")
}