You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin实现保护代理模式时InvocationHandler调用报错如何解决?

问题原因

  1. 无限递归触发Exception B
    你在处理get开头的方法时,method.invoke的第一个参数传了代理对象proxy本身。代理对象的所有方法调用都会转发到InvocationHandler的invoke方法,这就导致你调用ownerProxy.getName()时会进入死循环,无限触发invoke逻辑,最终触发JVM报错也就是你看到的Exception B。
  2. 参数数量不匹配触发Exception A
    Java的Method.invoke方法签名为invoke(Object obj, Object... args),当方法本身没有入参时,你不需要额外传args参数。你直接传了args(getName方法没有入参所以args为null),等于给无参方法多传了一个null参数,参数数量不匹配所以抛出IllegalArgumentException。

修复方案

修改OwnerInvocationHandler中get方法分支的调用逻辑:

  • 将invoke的第一个参数替换为真实的被代理对象person
  • 处理可变参数传递的Kotlin语法适配,用展开运算符*处理可空的参数数组

修复后的代码

class OwnerInvocationHandler(private val person: Person) : InvocationHandler {
    override fun invoke(proxy: Any?, method: Method, args: Array<Any>?): Any? {
        try {
            val methodName = method.name
            if (methodName.isNullOrEmpty())
                return null

            if (methodName.startsWith("get")) {
                // 第一个参数传真实对象person,参数数组用*展开适配Java可变参数
                return method.invoke(person, *args.orEmpty())
            } else if (methodName.startsWith("set")) {
                return method.invoke(person, *args.orEmpty())
            }
        } catch (e: InvocationTargetException) {
            e.printStackTrace()
        }
        return null
    }
}

额外说明

参数适配是Kotlin调用Java可变参数的常见注意点,但本次问题的核心错误是调用方法时传错了目标对象导致无限递归。修复后运行代码即可正常输出Name is Joe Javabean。

内容的提问来源于stack exchange,提问作者jjz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 04:06:03