java.lang.IllegalArgumentException:Callable需要4个参数,但提供了3个参数
我试图调用一个函数使用Kotlin反射,但我得到的错误:
java.lang.IllegalArgumentException:Callable需要4个参数,但提供了3个参数。
这是做反射电话的代码:
annotation.listeners.forEach { listener: KClass<*> -> listener.functions.forEach { function: KFunction<*> -> if (function.name == "before") { function.call(annotation.action, request, response) } } }
我已经为listener
和function
添加了类型,只是为了使问题更具可读性。
这是被调用的方法:
fun before(action: String, request: RestRequest, response: RestResponse)
为了仔细检查我的类型是否正确,我做了这个:
if (function.name == "before") { println(annotation.action::class) println(request::class) println(response::class) }
这将打印(这是before
函数所需的正确类型):
class kotlin.String class com.mycompany.RestRequest class com.mycompany.RestResponse
第四个参数应该是什么?
你错过了这个方法应该被调用的对象的“this”参数。
它应该是该方法的第一个参数
这不是直接显而易见的,但让我们来看看KCallable
的文档:
/** * Calls this callable with the specified list of arguments and returns the result. * Throws an exception if the number of specified arguments is not equal to the size of [parameters], * or if their types do not match the types of the parameters */ public fun call(vararg args: Any?): R
“如果参数个数不等于[parameters] […]的大小,则抛出异常”。 另一方面,参数是具有以下DOC的List<KParameter>
:
/** * Parameters required to make a call to this callable. * If this callable requires a `this` instance or an extension receiver parameter, * they come first in the list in that order. */ public val parameters: List<KParameter>
“如果这个可调用的需要一个this
实例[它]首先在列表中的顺序。”
就像bennyl已经正确回答了一样, this
实例是第一个参数,因为这个方法需要一个实例被调用。
你可以看看parameter
的内容:
class X{ fun before(action: String, request: String, response: String)= println("called") } fun main(args: Array<String>) { X::class.functions.forEach { function: KFunction<*> -> if (function.name == "before") { function.parameters.forEach{ println(it)} //function.call(X(), "a", "b", "c") } } }
打印的parameter
如下所示:
有趣的实例de.swirtz.jugcdemo.prepared.X.before(kotlin.String,kotlin.String,kotlin.String):kotlin.Unit
参数#1动作的乐趣de.swirtz.jugcdemo.prepared.X.before(kotlin.String,kotlin.String,kotlin.String):kotlin.Unit
参数#2请求的乐趣de.swirtz.jugcdemo.prepared.X.before(kotlin.String,kotlin.String,kotlin.String):kotlin.Unit
参数#3响应的乐趣de.swirtz.jugcdemo.prepared.X.before(kotlin.String,kotlin.String,kotlin.String):kotlin.Unit