Kotlin如何通过字符串名称动态调用对应函数?
Kotlin通过字符串方法名动态调用函数的实现方案
方案1:预建立字符串与函数的映射表(更推荐,无性能损耗、类型安全)
这种方案不需要用到反射,提前把允许调用的方法和对应字符串做绑定,编译期就能校验参数和返回值类型,不会出现运行时方法找不到、参数不匹配的崩溃问题,适配你给出的示例场景完全够用。
实现代码如下:
class MethodPicker() { val commands = listOf("foo", "tango") // 建立字符串到方法的映射表,值类型是接收一个String参数、无返回值的函数类型 private val methodMap = mapOf<String, (String) -> Unit>( "foo" to ::foo, "tango" to ::tango ) fun messageReceiver() { val messageParam : String = "Hi stackoverflow!" // 直接从映射表取方法执行,还可以加空判断避免非法方法名调用 methodMap[commands.random()]?.invoke(messageParam) } fun foo(message: String) { println(message + "foo!") } fun tango(message: String) { println(message + "tango!") } }
如果需要动态增删可调用的方法,把map换成mutableMap操作即可。
方案2:使用反射实现(适配高动态性场景)
如果可调用的方法数量极多、或者方法名是运行时完全动态生成的,没法提前写映射表,可以用反射实现,但是要注意反射有额外性能开销,且方法名、参数不匹配时会直接抛出运行时异常,需要做好异常捕获。
实现代码如下:
class MethodPicker() { val commands = listOf("foo", "tango") fun messageReceiver() { val messageParam : String = "Hi stackoverflow!" invokeMethod(commands.random(), messageParam) } private fun invokeMethod(methodName: String, param: String) { runCatching { // 从当前类的成员中查找对应名称、参数匹配的方法 val targetMethod = this::class.members.first { it.name == methodName && it.parameters.size == 2 // 第一个参数是类实例本身,第二个是入参 } // 调用方法,第一个参数传当前类实例,之后传入方法参数 targetMethod.call(this, param) }.onFailure { // 捕获方法不存在、参数不匹配等异常,按需处理 it.printStackTrace() } } fun foo(message: String) { println(message + "foo!") } fun tango(message: String) { println(message + "tango!") } }
注意:反射方案的参数校验逻辑可以按需扩展,比如可以校验参数类型是否匹配,进一步避免调用异常。
内容的提问来源于stack exchange,提问作者Blazerg
相关产品推荐
相关产品推荐

