为什么Kotlin在使用代理时抛出IllegalArgumentException [英] Why is Kotlin throw IllegalArgumentException when using Proxy
问题描述
这是使用InvocationHandler
的Java代码的Kotlin等效项:
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代码:
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代码给出了异常
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
Kotlin使用标准Java类是什么原因?
What is the cause of this as Kotlin is using the standard Java class?
推荐答案
在Kotlin中将args
传递到method!!.invoke(obj, args)
时,它实际上是数组类型的单个参数,默认情况下不会分解作为单独的参数.
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.
要实现该行为,请使用 spread运算符:*args
To achieve that behavior instead, use the spread operator: *args
val ret = method!!.invoke(obj, *args)
使用这种语法,将以与Java varargs中相同的方式传递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")
注意:如果某个方法没有任何参数,则args
将为null
,并将其在Kotlin中传播将导致为NullPointerException
.作为解决方法,请使用*(args ?: arrayOfNulls<Any>(0))
,然后在描述的特殊情况下,选择正确的部分并将其扩展为 zero 自变量.
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.
我的示例代理实现:
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))
输出为:
Before; args: [1, 2]
After; result: 3
3
这篇关于为什么Kotlin在使用代理时抛出IllegalArgumentException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!