我不知道这是一个错误还是一个功能,但对于跟踪异常原因的Java背景的人来说,这肯定是不直观的。
即使未定义变量,Groovy也允许引用变量。 例如,考虑以下类:
class B {
def infos;
public B(String param)
{
infos = param
}
public getInfo()
{
return info;
}
}
如果您注意到,在getInfo()
内,我将返回永远未定义的info
。但是,Eclipse没有发出警告。所以我继续写下面的内容:
class A
{
static main(def args)
{
B bObj = new B("Mahesh")
println "Hello groovy"
println bObj.getInfo()
println "Hello groovy"
}
}
现在这为StackOverflowError
提供了一个巨大的堆栈跟踪:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.Exception.<init>(Exception.java:102)
at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89)
at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at groovy.lang.MetaClassImpl$GetBeanMethodMetaProperty.getProperty(MetaClassImpl.java:3493)
at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.callGroovyObjectGetProperty(GetEffectivePogoPropertySite.java:67)
--> at packages.B.getInfo(ThreadDumpsExp.groovy:169) <--
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at groovy.lang.MetaClassImpl$GetBeanMethodMetaProperty.getProperty(MetaClassImpl.java:3493)
at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.callGroovyObjectGetProperty(GetEffectivePogoPropertySite.java:67)
:
:
此处的堆栈跟踪是正常的,因为堆栈跟踪中的某处向下指向此特定行,我在上面的堆栈跟踪中用箭头突出显示。我期待堆栈跟踪中的这一行,这就是我能够快速跟踪它的原因。这个问题出现了,今天我在我的项目中遇到了同样的问题。堆栈跟踪同样巨大。我不知道它实际上出了什么问题,所以我无法猜测哪条线可能实际上是错误的。最糟糕的是它在调试期间停止在Groovy的源代码中。我不得不反复在不同的地方放置断点来实际停止执行它们。一段时间后,我发现调试器实际停在我的代码中的行。从那里我逐步完成整个代码,找到导致问题的那一行。这条线是一个简单的吸气剂,它返回了错误的东西。
现在我知道在编写代码时我应该更有意识,并且不应该犯这样的错误,即从getter返回一个不存在的变量。但有没有办法让它不做上面做的事情?
修改
此外,在添加@TypeChecked
后,会出现以下错误。它之前的工作正常。
答案 0 :(得分:2)
问题在于getInfo-Method的签名,这意味着这是一个getter。当你调用一个类的属性(这里用&#34;返回信息&#34;)而不是隐式groovy使用getter getInfo。这会创建一个无限循环,导致StackOverflowError(因为info调用getInfo,getInfo调用info,调用getInfo ...)。如果你在这里使用另一个不存在的属性(即return foo),你会收到预期的MissingPropertyException。为避免此行为,您不应定义名称与不存在的属性匹配的getter-Methods。
答案 1 :(得分:2)
为属性添加getter时,无论属性是否存在,都需要使用.@
运算符引用该属性。这是直接的现场访问操作员,它跳过任何吸气剂并直接前往酒店。如果您不使用运算符,则会反复调用相同的getter,直到获得StackOverflowError
。
例如:
def getInfo() {
return this.@info
}
请参阅Groovy operator docs中的第6.2节直接字段访问运算符以获取更多信息。