??通過反射調(diào)用函數(shù)需要 KFunction 實例,KFunction 實例可以通過兩種方式獲得:一種是函數(shù)引用;另外一種是通過 KClass 提供的 API 獲得 KFunction 實例。
??函數(shù)引用可以表示一個函數(shù)字面量,可以賦值給函數(shù)類型變量。函數(shù)引用也是使用 :: 運算符,可以引用頂層函數(shù)也可以引用類中的成員函數(shù)。
- 通過反射調(diào)用函數(shù)的示例代碼如下:
class Person() {
var name: String? = null
var age: Int = 0
fun setNameAndAge(name: String, age: Int) {
this.name = name
this.age = age
}
override fun toString(): String {
return "Person [name=$name, age=$age]"
}
}
fun add(a: Int, b: Int): Int = a + b
fun sub(a: Int, b: Int) = a - b
fun calculate(opr: Char): (Int, Int) -> Int = if (opr === '+') ::add else ::sub
fun main(args: Array<String>) {
val fn1 = ::add // 1??
val fn2 = ::sub // 2??
val fn3 = calculate('+') // 3??
println(fn1.call(10, 5)) // 4??15
println(fn1(10, 5)) // 5??15
println(fn2(10, 5)) // 5
println(fn3(10, 5)) // 15
val clz = Person::class // 6??
val person = clz.createInstance() // 7??
clz.functions.forEach { println(it.name) } // 8??
val pfn1 = clz.functions.first()
pfn1.call(person, "小三", 18)
println(person)
val pfn2 = Person::setNameAndAge
pfn2.call(person, "小五", 15)
println(person)
pfn2.call(person, "小雪", 20)
println(person)
}
運行結(jié)果:
15
15
5
15
setNameAndAge
toString
equals
hashCode
Person [name=小三, age=18]
Person [name=小五, age=15]
Person [name=小雪, age=20]
Process finished with exit code 0
??上面代碼第1??、2??行都是引用頂層函數(shù)。代碼第3??行調(diào)用 calculate 函數(shù),該函數(shù)的返回類型是函數(shù)類型 (Int, Int) -> Int,函數(shù)引用可以作為函數(shù)字面量表示函數(shù),所以 calculate 函數(shù)直接返回函數(shù)引用。這也說明了 KFunction 類型與函數(shù)類型是兼容的。
??代碼第4??行是通過 KFunction 的 call 函數(shù)調(diào)用引用的函數(shù),也可以通過第5??行直接調(diào)用函數(shù)。
??代碼第6??行是引用 Person 類實例,代碼第7??行是通過引用類創(chuàng)建實例 Person,createInstance 函數(shù)能夠創(chuàng)建引用類的對象。代碼第8??行 functions 是 KClass 屬性,它可以獲得當(dāng)前類中的所有函數(shù)。