This is the Kotlin equivalent of Java code using InvocationHandler
:
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
println("before httprequest--->" + args)
val ret = method!!.invoke(obj, args)
println("after httprequest--->")
return ret
}
Java code:
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;
}
In both case args
is null , But if I run it, Kotlin code is giving Exception
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
What is the cause of this as Kotlin is using the standard Java class?
When you pass args
into method!!.invoke(obj, args)
in Kotlin, it is actually a single argument of array type, and by default it is not decomposed into its elements as separate arguments.
To achieve that behavior instead, use the spread operator: *args
val ret = method!!.invoke(obj, *args)
With this syntax, args
will be passed in the same way as in Java varargs. For example, these lines of code are equivalent:
someVarargsFunction("a", "b", "c", "d", "e")
someVarargsFunction("a", "b", *arrayOf("c", "d"), "e")
Note: if a method doesn't have any parameters, args
will be null
, and spreading it in Kotlin would result into a NullPointerException
. As a workaround, use *(args ?: arrayOfNulls<Any>(0))
, and in the described corner case the right part is chosen and spread into zero arguments.
My example proxy implementation:
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<Any>(0)))
println("After; result: $ret")
ret
} as SomeInterface
println(a.f(1, 2))
And the output is:
Before; args: [1, 2] After; result: 3 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With