Koltin的動態(tài)代理的坑。
1.Kotlin中動態(tài)代理的實(shí)現(xiàn)。
class DynamicProxy constructor(any: Any): InvocationHandler{
private val mAny: Any = any
@Throws(Throwable::class)
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
return method!!.invoke(mAny,args)
}
}
2.運(yùn)行報(bào)錯(cuò)信息:
Caused by: java.lang.IllegalArgumentException: method ....xxx argument 1 has type java.lang.String, got java.lang.Object[]
3.原因:
(1)在invoke方法中接收可變長參數(shù),在Kotlin語法中,數(shù)組是array,可變長參數(shù)類型是vararg,類型不匹配。
(2)Kotlin中數(shù)組轉(zhuǎn)為可變長參數(shù),通過前面加*符號。
(3)如果方法沒有任何參數(shù),args將為null,并將其傳播到Kotlin將導(dǎo)致NullPointerException.作為一種解決方法,使用*(args?:arrayOfNulls< Any>(0)),并在所描述的極端情況下選擇正確的部分并將其擴(kuò)展為零參數(shù).「參考文檔」
4.修改后的Koltin動態(tài)代理實(shí)現(xiàn)
class DynamicProxy constructor(any: Any): InvocationHandler{
private val mAny: Any = any
@Throws(Throwable::class)
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
// return method!!.invoke(mAny,args)
return method!!.invoke(mAny,*(args ?: emptyArray()))
}
}
經(jīng)過以上的修改,你以為就可以了。錯(cuò)?。。?!kotlin還有另外一個(gè)坑。
5.錯(cuò)誤日志:
運(yùn)行上面的修改后的代碼。出現(xiàn)以下錯(cuò)誤提示:
Caused by: java.lang.IllegalStateException: method!!.invoke(mAny,*(args ?: emptyArray())) must not be null
6.原因
(1)同樣是類型不匹配導(dǎo)致,invoke的方法可能是沒有返回值的,所以需要將any類型變成any?類型。
(2)在kotlin中存在類型和子類型兩種概念,比如any和any?類型。比如在任何使用any?的地方,都可以傳入any類型的變量,但是反過來卻不可以。
7.完整實(shí)現(xiàn)邏輯:
class DynamicProxy constructor(any: Any): InvocationHandler{
private val mAny: Any = any
@Throws(Throwable::class)
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
// return method!!.invoke(mAny,args)
return method!!.invoke(mAny,*(args ?: emptyArray()))
}
}