java.lang.IllegalArgumentException:Callable需要4个参数,但提供了3个参数

时间:2017-09-09 10:15:07

标签: reflection kotlin

我正在尝试使用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

第四个参数应该是什么?

2 个答案:

答案 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