关闭检查导致意外的堆栈溢出错误
Closure examination causing unexpected Stack Overflow Error
我正在尝试使用此代码来更好地理解 this
、owner
和 delegate
如何在 Groovy 闭包中工作:
class GroovyTest {
static void main(String[] args) {
examine() {
println 'In first closure'
println "class is ${getClass().name}"
println "this is $this, super: ${this.getClass().getSuperclass().name}"
println "owner is $owner, super: ${owner.getClass().getSuperclass().name}"
println "delegate is $delegate, super: ${delegate.getClass().getSuperclass().name}"
examine() {
println 'In closure within the closure'
println "class is ${getClass().name}"
println "this is $this, super: ${this.getClass().getSuperclass().name}"
println "owner is $owner, super: ${owner.getClass().getSuperclass().name}"
println "delegate is $delegate, super: ${delegate.getClass().getSuperclass().name}"
}
}
}
static examine(closure) {
closure()
}
}
当我执行这段代码时,它会导致堆栈溢出错误,但是我很难找出导致无限递归的原因。我在这里包含了部分堆栈跟踪:
Caught: java.lang.WhosebugError
java.lang.WhosebugError
at GroovyTest$_main_closure1.doCall(GroovyTest.groovy:10)
at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy:14)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy)
at jdk.internal.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest.examine(GroovyTest.groovy:21)
at jdk.internal.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest$_main_closure1.doCall(GroovyTest.groovy:10)
at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy:14)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy)
at jdk.internal.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest.examine(GroovyTest.groovy:21)
似乎是行 println "owner is $owner, super: ${owner.getClass().getSuperclass().name}"
引起了无限递归。
为什么此代码会导致堆栈溢出错误,我该如何解决?
Edit:以下脚本也包含嵌套闭包,完全按预期工作。堆栈溢出异常不是由嵌套闭包本身引起的。好像跟打印语句有关系
def examiningClosure(closure) {
closure()
}
examiningClosure() {
println "In First Closure:"
println "class is " + getClass().name
println "this is " + this + ", super:" + this.getClass().superclass.name
println "owner is " + owner + ", super:" + owner.getClass().superclass.name
println "delegate is " + delegate +
", super:" + delegate.getClass().superclass.name
examiningClosure() {
println "In Closure within the First Closure:"
println "class is " + getClass().name
println "this is " + this + ", super:" + this.getClass().superclass.name
println "owner is " + owner + ", super:" + owner.getClass().superclass.name
println "delegate is " + delegate +
", super:" + delegate.getClass().superclass.name
}
}
好的,首先我要为没有花时间仔细研究这个问题而道歉。
将尝试用实际解释来弥补它。
原来是下面的代码:
def c = {
println "foo"
}
println "${c}"
有点不直观地导致闭包被执行,而不是仅仅在标准输出上打印它的字符串表示:
─➤ groovy test.groovy
foo
所以在你的例子中:
class GroovyTest {
static void main(args) {
examine { // closure 1
examine { // closure 2
println "${owner}"
}
}
}
static examine(closure) {
closure()
}
}
(examine
方法调用后的括号可以省略)
最里面的闭包的owner
就是最里面的闭包本身。调用封闭闭包将导致自调用的无限递归,最终导致 WhosebugException
.
您可以通过例如 println "${owner.getClass()}"
来解决此问题,这会阻止隐式闭包调用。
我不得不说来自 "${closure}"
的闭包调用非常不直观,根本不是我所期望的......经过多年使用 groovy......但它就是这样是。
我正在尝试使用此代码来更好地理解 this
、owner
和 delegate
如何在 Groovy 闭包中工作:
class GroovyTest {
static void main(String[] args) {
examine() {
println 'In first closure'
println "class is ${getClass().name}"
println "this is $this, super: ${this.getClass().getSuperclass().name}"
println "owner is $owner, super: ${owner.getClass().getSuperclass().name}"
println "delegate is $delegate, super: ${delegate.getClass().getSuperclass().name}"
examine() {
println 'In closure within the closure'
println "class is ${getClass().name}"
println "this is $this, super: ${this.getClass().getSuperclass().name}"
println "owner is $owner, super: ${owner.getClass().getSuperclass().name}"
println "delegate is $delegate, super: ${delegate.getClass().getSuperclass().name}"
}
}
}
static examine(closure) {
closure()
}
}
当我执行这段代码时,它会导致堆栈溢出错误,但是我很难找出导致无限递归的原因。我在这里包含了部分堆栈跟踪:
Caught: java.lang.WhosebugError
java.lang.WhosebugError
at GroovyTest$_main_closure1.doCall(GroovyTest.groovy:10)
at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy:14)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy)
at jdk.internal.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest.examine(GroovyTest.groovy:21)
at jdk.internal.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest$_main_closure1.doCall(GroovyTest.groovy:10)
at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy:14)
at GroovyTest$_main_closure1$_closure2.doCall(GroovyTest.groovy)
at jdk.internal.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at GroovyTest.examine(GroovyTest.groovy:21)
似乎是行 println "owner is $owner, super: ${owner.getClass().getSuperclass().name}"
引起了无限递归。
为什么此代码会导致堆栈溢出错误,我该如何解决?
Edit:以下脚本也包含嵌套闭包,完全按预期工作。堆栈溢出异常不是由嵌套闭包本身引起的。好像跟打印语句有关系
def examiningClosure(closure) {
closure()
}
examiningClosure() {
println "In First Closure:"
println "class is " + getClass().name
println "this is " + this + ", super:" + this.getClass().superclass.name
println "owner is " + owner + ", super:" + owner.getClass().superclass.name
println "delegate is " + delegate +
", super:" + delegate.getClass().superclass.name
examiningClosure() {
println "In Closure within the First Closure:"
println "class is " + getClass().name
println "this is " + this + ", super:" + this.getClass().superclass.name
println "owner is " + owner + ", super:" + owner.getClass().superclass.name
println "delegate is " + delegate +
", super:" + delegate.getClass().superclass.name
}
}
好的,首先我要为没有花时间仔细研究这个问题而道歉。
将尝试用实际解释来弥补它。
原来是下面的代码:
def c = {
println "foo"
}
println "${c}"
有点不直观地导致闭包被执行,而不是仅仅在标准输出上打印它的字符串表示:
─➤ groovy test.groovy
foo
所以在你的例子中:
class GroovyTest {
static void main(args) {
examine { // closure 1
examine { // closure 2
println "${owner}"
}
}
}
static examine(closure) {
closure()
}
}
(examine
方法调用后的括号可以省略)
最里面的闭包的owner
就是最里面的闭包本身。调用封闭闭包将导致自调用的无限递归,最终导致 WhosebugException
.
您可以通过例如 println "${owner.getClass()}"
来解决此问题,这会阻止隐式闭包调用。
我不得不说来自 "${closure}"
的闭包调用非常不直观,根本不是我所期望的......经过多年使用 groovy......但它就是这样是。