2017-09-09 1 views
1
vorgesehen

Ich versuche, eine Funktion Kotlin Reflexion aufrufen, aber ich bin immer die Fehlermeldung:java.lang.IllegalArgumentException: Callable erwartet 4 Argumente, aber 3 wurden

java.lang.IllegalArgumentException: Callable expects 4 arguments, but 3 were provided.

Dies ist der Code tun die reflektierende Anruf:

annotation.listeners.forEach { listener: KClass<*> -> 
     listener.functions.forEach { function: KFunction<*> -> 
      if (function.name == "before") { 
       function.call(annotation.action, request, response) 
      } 
     } 
    } 

I-Typen für listener und function gerade hinzugefügt haben die Frage besser lesbar zu machen.

Dies ist die Methode, die aufgerufen wird wird:

fun before(action: String, request: RestRequest, response: RestResponse) 
überprüfen

zu verdoppeln, dass meine Typen korrekt sind, habe ich dies:

if (function.name == "before") { 
    println(annotation.action::class) 
    println(request::class) 
    println(response::class) 
} 

Diese Drucke (die die richtigen Typen für die benötigt wird, before Funktion):

class kotlin.String 
class com.mycompany.RestRequest 
class com.mycompany.RestResponse 

Was sollte der vierte Parameter sein?

Antwort

1

Ihnen fehlt der "this" -Parameter, der das Objekt ist, für das die Methode aufgerufen werden soll.

sollte es sein, das erste Argument der Methode

+0

ah, ja, es muss natürlich eine Instanz es auf rufen . –

1

Es direkt nicht offensichtlich ist, aber schauen wir uns die doc von KCallable einen Blick:

/** 
* 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 

„Löst eine Ausnahme aus, wenn die Anzahl der Argumente ist nicht gleich der Größe von [Parameter] [...] ". Parameter auf der anderen Seite ist ein List<KParameter> mit folgenden DOC: "Wenn diese aufrufbar eine this Instanz benötigt [...] [it] kommen [s] zuerst in der Liste in dieser Reihenfolge"

/** 
* 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> 

Wie bennyl bereits richtig beantwortet, ist eine this Instanz der erste Parameter, der vor den anderen drei kommt, weil die Methode eine Instanz benötigt, um aufgerufen zu werden.

Sie können es sehen, wenn Sie bei parameter ‚s Inhalt aussehen:

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

Die gedruckte parameter sieht wie folgt aus:

instance of fun de.swirtz.jugcdemo.prepared.X.before(kotlin.String, kotlin.String, kotlin.String): kotlin.Unit

parameter #1 action of fun de.swirtz.jugcdemo.prepared.X.before(kotlin.String, kotlin.String, kotlin.String): kotlin.Unit

parameter #2 request of fun de.swirtz.jugcdemo.prepared.X.before(kotlin.String, kotlin.String, kotlin.String): kotlin.Unit

parameter #3 response of fun de.swirtz.jugcdemo.prepared.X.before(kotlin.String, kotlin.String, kotlin.String): kotlin.Unit

+0

Ich sah, dass, wenn ich eine Inspektion auf der "Call" -Methode machte, daher der Grund, warum ich die Typen in meiner Frage gedruckt habe, um zu bestätigen, dass meine Typen korrekt sind. Wo hast du den zweiten Kommentarblock gefunden? Wäre schön, wenn der erste Kommentarblock erwähnt, dass der erste Parameter die Instanz sein sollte, obwohl es wahrscheinlich offensichtlich ist, wenn Sie es vorher getan haben. –

+0

Es ist beides in 'KCallable' :) – s1m0nw1

+0

Ah, richtig,' Ruft dies aufrufbar mit dem angegebenen ', dass' das 'tatsächlich bezieht sich auf die Instanz, habe ich diesen Satz etwas anders verstanden, wenn ich es im Quellcode und in Ihrem lesen Kopieren Sie den Kommentarblock. Der zweite Kommentarblock wäre sofort offensichtlich gewesen. –

Verwandte Themen