2017-09-09 44 views
1

を提供された:java.lang.IllegalArgumentExceptionが:コーラブルは4つの引数を期待していますが、3は、私はKotlinの反射を使用して関数を呼び出すためにしようとしているが、私はエラーを取得しています

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

は、これはコードやっています反射コール:

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 

第4パラメータは何ですか?

答えて

1

メソッドが呼び出されるオブジェクトである「this」パラメータがありません。

それはそれは直接明らかではありません方法

+0

ああ、はい、明らかにそれを呼び出すためにインスタンスを必要とします。 –

1

の最初の引数であってもよいが、のは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] [...]のサイズと同じではありません。 「そのために、この呼び出し可能にthisインスタンスを必要とする場合は、[...] [それは]最初のリストに[s]が来る。」

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

:一方、パラメータ次のDOCとList<KParameter>です

ベニールは既に正しく答えられているように、thisインスタンスが最初のパラメータであり、メソッドが呼び出される必要があるため、残りの3つのパラメータの前に来ます。

あなたは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次のようになります。

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

私は 'call'メソッドの検査をしたときに、私のタイプが正しいことを確認するためにタイプを印刷しました。 2番目のコメントブロックはどこにありますか?最初のコメントブロックで最初のparamがインスタンスになるはずだと言われたらいいですか? –

+0

それは 'KCallable'にあります:) – s1m0nw1

+0

ああ、'指定された呼び出し可能オブジェクトを呼び出します。 'これは実際にインスタンスを参照しています。私はソースコードとあなたのコメントブロックのコピー貼り付け。 2番目のコメントブロックはすぐに明白でした。 –

関連する問題

 関連する問題