为什么Kotlin在使用代理时抛出IllegalArgumentException [英] Why is Kotlin throw IllegalArgumentException when using Proxy

查看:356
本文介绍了为什么Kotlin在使用代理时抛出IllegalArgumentException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是使用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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆