我正在尝试使用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
第四个参数应该是什么?
答案 0 :(得分:4)
你错过了&#34;这个&#34;参数,该方法应该相对于该方法调用。
它应该是方法的第一个参数
答案 1 :(得分:4)
直接并不明显,但让我们来看看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
实例[...] [它]按顺序首先出现在[s]列表中。”
与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 action of fun 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 of fun de.swirtz.jugcdemo.prepared.X.before(kotlin.String,kotlin.String,kotlin.String):kotlin.Unit