Kotlin实现保护代理模式时InvocationHandler调用报错如何解决?
问题原因
- 无限递归触发Exception B
你在处理get开头的方法时,method.invoke的第一个参数传了代理对象proxy本身。代理对象的所有方法调用都会转发到InvocationHandler的invoke方法,这就导致你调用ownerProxy.getName()时会进入死循环,无限触发invoke逻辑,最终触发JVM报错也就是你看到的Exception B。 - 参数数量不匹配触发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
相关产品推荐
相关产品推荐

