Koltinの動的エージェントInvocationHandler

2020 ワード

Koltinのダイナミックエージェントのピット.
1.Kotlinにおける動的エージェントの実装.
class DynamicProxy constructor(any: Any): InvocationHandler{
    private val mAny: Any = any
    @Throws(Throwable::class)
    override fun invoke(proxy: Any?, method: Method?, args: Array?): Any {
        return method!!.invoke(mAny,args)
    }
}

2.エラーメッセージの実行:
Caused by: java.lang.IllegalArgumentException: method ....xxx argument 1 has type java.lang.String, got java.lang.Object[]

3.理由:
(1)invokeメソッドでは可変長パラメータを受信し,Kotlin構文では配列がarray,可変長パラメータタイプがvararg,タイプが一致しない.
(2)Kotlinでは配列が可変長パラメータに変わり,前に*記号を付ける.
(3)メソッドにパラメータがない場合、argsはnullとなり、Kotlinに伝播するとNullPointerExceptionとなる.1つの解決策として*(args?:arrayOfNulls(0))を用いる、記載の極端の場合に正しい部分を選択してゼロパラメータに拡張する.「参考文献」
4.修正後のKoltin動的エージェント実装
class DynamicProxy constructor(any: Any): InvocationHandler{
    private val mAny: Any = any
    @Throws(Throwable::class)
    override fun invoke(proxy: Any?, method: Method?, args: Array?): Any {
//        return method!!.invoke(mAny,args)
        return method!!.invoke(mAny,*(args ?: emptyArray()))
    }
}

以上の修正を経て、あなたはそれでいいと思います.間違いだ!!!kotlinにはもう一つの穴があります.
5.エラーログ:上記の修正コードを実行します.次のエラーメッセージが表示されます.
 Caused by: java.lang.IllegalStateException: method!!.invoke(mAny,*(args ?: emptyArray())) must not be null

6.理由(1)同様にタイプが一致しないため、invokeの方法は値を返さない可能性があるので、anyタイプをanyにする必要がありますか?を選択します.(2)kotlinにはanyとanyのようなタイプとサブタイプの2つの概念が存在する.を選択します.例えばanyはどんな使用ですか?の場合、anyタイプの変数を入力できますが、逆にはできません.
7.完全な実装ロジック:
class DynamicProxy constructor(any: Any): InvocationHandler{
    private val mAny: Any = any
    @Throws(Throwable::class)
    override fun invoke(proxy: Any?, method: Method?, args: Array?): Any? {
//        return method!!.invoke(mAny,args)
        return method!!.invoke(mAny,*(args ?: emptyArray()))
    }
}

8.参考記事:Kotlinダイナミックエージェントの実装によるException