错误getter的groovy问题
我不知道这是一个bug还是一个特性,但对于Java背景的人来说,跟踪异常原因肯定是不直观的 Groovy允许引用变量,即使没有定义变量。 例如,考虑下面的类:错误getter的groovy问题,groovy,Groovy,我不知道这是一个bug还是一个特性,但对于Java背景的人来说,跟踪异常原因肯定是不直观的 Groovy允许引用变量,即使没有定义变量。 例如,考虑下面的类: class B { def infos; public B(String param) { infos = param } public getInfo() { return info; } } 如果您注意到,在getInfo()中,我返回了从未
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"
}
}
现在,这给了stackoverflowerrror
一个巨大的堆栈跟踪:
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)
:
:
线程“main”java.lang.StackOverflower中出现异常
位于java.lang.Exception。(Exception.java:102)
位于java.lang.ReflectiveOperationException。(ReflectiveOperationException.java:89)
位于java.lang.reflect.InvocationTargetException。(InvocationTargetException.java:72)
在sun.reflect.GeneratedMethodAccessor1.invoke处(未知源)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:601)
位于org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
位于groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
位于groovy.lang.MetalassImpl$GetBeanMethodMetaProperty.getProperty(MetalassImpl.java:3493)
位于org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.callGroovyObjectGetProperty(GetEffectivePogoPropertySite.java:67)
-->在packages.B.getInfo(ThreadDumpsExp.groovy:169)中,问题在于getInfo方法的签名,这意味着这是一个getter。当您调用一个类的属性(这里带有“return info”)时,groovy会隐式地使用getter getInfo。这会创建一个无休止的循环,导致StackOverflowerError(因为info调用getInfo,getInfo调用info,调用getInfo…)。如果您在此处使用另一个不存在的属性(即return foo),您将收到预期的MissingPropertyException。要避免此行为,不应定义名称与不存在的属性匹配的getter方法。为属性添加getter时,无论该属性是否存在,都需要使用
@
运算符引用该属性。这是直接字段访问操作符,它跳过任何getter并直接进入属性。如果不使用该运算符,则会反复调用同一个getter,直到得到stackoverflowerrror
例如:
def getInfo() {
return this.@info
}
有关更多信息,请参阅中的第6.2节直接字段访问运算符。在类或方法上使用@TypeChecked注释,它在这方面的行为更像Java。不知何故,现在的问题是,方法名
getInfo
阻止编译器显示错误。(添加了上述问题的屏幕截图。)如果我将getInfo()
更改为getInfos()
。它正确地给出了@TypeChecked
的错误。哦,确实如此,所以没有解决办法让编译器捕捉到这个错误?我只是误解了这一特性是一个问题吗?我认为通常情况下,除非您真的需要,否则您可以通过不在Groovy中定义getter来避免这种问题。Groovy为您定义了所有标准的getter和setter。如果你需要特殊的行为,你只需要覆盖它们。这听起来是一个精确的解决办法,但是如果你不能像myy问题中最后一张图片所示,用默认的
和@TypeChecked
,你不需要@TypeChecked
。一旦你添加了它,它就指出你的代码并没有按照你想象的那样工作。你认为你在增加一个数字,但实际上它在对一个对象调用next()-remove@TypeChecked
,我认为你不会得到你想要的。为什么我不能用OP的代码重现SOE?我使用的是Groovy版本2.4.15
。