报错‘Could not compute caller for function’:如何反射调用plus函数?
问题分析与解决方案
错误原因
你遇到的KotlinReflectionInternalError是因为Int的plus函数属于Kotlin内置优化(Intrinsic)函数,这类函数由编译器直接生成字节码优化,没有对应的常规JVM方法实现,Kotlin反射无法直接调用它,因此触发内部错误。
正确实现方式
方案一:分类型处理(简单直接)
针对常见支持plus操作的类型(数值、字符串等)直接处理,自定义类型则尝试Kotlin反射调用:
class C<T>(var x: T) inline fun <reified T> f(a: C<T>, b: C<T>): T? { val aVal = a.x val bVal = b.x return when (T::class) { Int::class -> (aVal as Int + bVal as Int) as T Long::class -> (aVal as Long + bVal as Long) as T Float::class -> (aVal as Float + bVal as Float) as T Double::class -> (aVal as Double + bVal as Double) as T String::class -> (aVal as String + bVal as String) as T else -> { runCatching { T::class.members .filterIsInstance<kotlin.reflect.KFunction<T>>() .firstOrNull { it.name == "plus" && it.parameters.size == 2 && it.parameters[1].type == T::class.createType() }?.call(aVal, bVal) }.getOrNull() } } } fun main(args: Array<String>) { val a = C(1) val b = C(2) println(f(a, b)) // 输出3 val s1 = C("Hello ") val s2 = C("World") println(f(s1, s2)) // 输出Hello World }
方案二:Java反射通用调用
利用Java反射兼容Kotlin内置类型的方法调用,同时处理基本类型的装箱情况:
class C<T>(var x: T) inline fun <reified T> f(a: C<T>, b: C<T>): T? { val aVal = a.x val bVal = b.x return try { val method = aVal.javaClass.getMethod("plus", bVal.javaClass) method.invoke(aVal, bVal) as T } catch (e: NoSuchMethodException) { // 处理基本类型的直接求和 when (T::class) { Int::class -> (aVal as Int + bVal as Int) as T Long::class -> (aVal as Long + bVal as Long) as T Float::class -> (aVal as Float + bVal as Float) as T Double::class -> (aVal as Double + bVal as Double) as T else -> null } } catch (_: Exception) { null } } fun main(args: Array<String>) { val a = C(1) val b = C(2) println(f(a, b)) // 输出3 }
补充说明
如果你的场景只需要支持数值类型,方案一的分支判断已经足够简洁可靠;如果需要支持更多自定义类型,方案二的Java反射能更好兼容Kotlin的操作符方法。
内容的提问来源于stack exchange,提问作者ramzes666
相关产品推荐
相关产品推荐

