Groovy闭包调用Owner时出现意外栈溢出问题咨询
问题解析与解决
1. 为什么bar闭包的owner不是预期的Tank$foo?
在Groovy中,闭包的owner是定义该闭包的上下文所有者,你的代码里存在一个关键逻辑误区:
foo闭包是作为Tank类的成员属性定义的,因此它的owner是Tank实例;bar闭包是在foo的执行逻辑内部定义的,但此时它的上下文仍然绑定到Tank实例,而非foo闭包本身。
Groovy闭包的owner核心规则:
- 直接定义在类中的闭包,
owner为类的实例; - 只有当闭包是作为另一个闭包的成员属性/静态嵌套定义时,内层闭包的
owner才会指向外层闭包。
你预期的Tank$foo其实是闭包的类名,而非owner的默认值。如果要让bar的owner指向foo闭包,需要显式修改绑定关系。
2. 关于StackOverflow错误
你提供的代码本身不会触发StackOverflow错误,大概率是测试时的代码存在递归调用(比如误将bar()写成foo())。如果确实出现该错误,优先检查是否存在闭包递归调用的情况。
修正代码(实现bar的owner为foo闭包)
如果想让bar闭包的owner指向foo闭包,可以显式设置闭包的owner属性:
class Tank { def foo = { println "Owner is $owner (${owner.getClass().name})" // 显式将bar的owner绑定为当前foo闭包 def bar = { println " Owner is $owner (${owner.getClass().name})" }.setOwner(this) // 此处的this指向foo闭包本身 bar() } static void main(String ...args){ def t = new Tank() t.foo() } }
运行输出示例:
Owner is Tank@7a79be86 (Tank) Owner is Tank$_run_closure1@6bc7c054 (Tank$_run_closure1)
这里的Tank$_run_closure1就是你预期的类似Tank$foo的闭包类名。
内容的提问来源于stack exchange,提问作者martsbradley
相关产品推荐
相关产品推荐

