这是Kotlin等效的Java代码,使用InvocationHandler
:
override fun invoke(proxy: Any?, method: Method?, args: Array?): Any { println("before httprequest--->" + args) val ret = method!!.invoke(obj, args) println("after httprequest--->") return ret }
Java代码:
public Object invoke(Object o, Method method, Object[] args) throws Throwable { System.out.println("jdk--------->http" + args); Object result=method.invoke(target, args); System.out.println("jdk--------->http"); return result; }
在这两种情况下args
都是null,但是如果我运行它,Kotlin代码就会给出异常
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
Kotlin使用标准Java类的原因是什么?
当你args
进入method!!.invoke(obj, args)
Kotlin时,它实际上是数组类型的单个参数,并且默认情况下它不会作为单独的参数分解为其元素.
要实现该行为,请使用spread运算符:*args
val ret = method!!.invoke(obj, *args)
使用此语法,args
将以与Java varargs相同的方式传递.例如,这些代码行是等效的:
someVarargsFunction("a", "b", "c", "d", "e") someVarargsFunction("a", "b", *arrayOf("c", "d"), "e")
注意:如果一个方法没有任何参数,那么args
将null
它传播到Kotlin会产生一个NullPointerException
.作为一种变通方法,使用*(args ?: arrayOfNulls
,并在描述的角落情况下,选择正确的部分并将其扩展为零参数.
我的示例代理实现:
interface SomeInterface { fun f(a: Int, b: Int): Int } val obj = object : SomeInterface { override fun f(a: Int, b: Int) = a + b }
val a = Proxy.newProxyInstance( SomeInterface::class.java.classLoader, arrayOf(SomeInterface::class.java)) { proxy, method, args -> println("Before; args: " + args?.contentToString()) val ret = method!!.invoke(obj, *(args ?: arrayOfNulls(0))) println("After; result: $ret") ret } as SomeInterface println(a.f(1, 2))
输出是:
Before; args: [1, 2] After; result: 3 3