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) } } } 

我已经为listenerfunction添加了类型,只是为了使问题更具可读性。

这是被调用的方法:

 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