为什么 Kotlin 在使用 Proxy 时会抛出 IllegalArgumentException
Why is Kotlin throw IllegalArgumentException when using Proxy
这是使用 InvocationHandler
:
的 Java 代码的 Kotlin 等价物
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 代码给出异常
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
Kotlin 使用的是标准 Java class,这是什么原因?
当你在Kotlin中将args
传递给method!!.invoke(obj, args)
时,它实际上是一个数组类型的参数,默认它不会被分解成它的元素作为单独的参数。
要实现该行为,请使用 spread operator:*args
val ret = method!!.invoke(obj, *args)
使用此语法,args
将以与 Java 可变参数相同的方式传递。例如,这些代码行是等价的:
someVarargsFunction("a", "b", "c", "d", "e")
someVarargsFunction("a", "b", *arrayOf("c", "d"), "e")
注意:如果一个方法没有任何参数,args
将是null
,在Kotlin中传播它会导致NullPointerException
。作为解决方法,使用 *(args ?: arrayOfNulls<Any>(0))
,在所描述的极端情况下,选择正确的部分并将其分散到 零 个参数中。
我的示例代理实现:
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
这是使用 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 代码给出异常
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
Kotlin 使用的是标准 Java class,这是什么原因?
当你在Kotlin中将args
传递给method!!.invoke(obj, args)
时,它实际上是一个数组类型的参数,默认它不会被分解成它的元素作为单独的参数。
要实现该行为,请使用 spread operator:*args
val ret = method!!.invoke(obj, *args)
使用此语法,args
将以与 Java 可变参数相同的方式传递。例如,这些代码行是等价的:
someVarargsFunction("a", "b", "c", "d", "e")
someVarargsFunction("a", "b", *arrayOf("c", "d"), "e")
注意:如果一个方法没有任何参数,args
将是null
,在Kotlin中传播它会导致NullPointerException
。作为解决方法,使用 *(args ?: arrayOfNulls<Any>(0))
,在所描述的极端情况下,选择正确的部分并将其分散到 零 个参数中。
我的示例代理实现:
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