错误getter的groovy问题

错误getter的groovy问题,groovy,Groovy,我不知道这是一个bug还是一个特性,但对于Java背景的人来说,跟踪异常原因肯定是不直观的 Groovy允许引用变量,即使没有定义变量。 例如,考虑下面的类: class B { def infos; public B(String param) { infos = param } public getInfo() { return info; } } 如果您注意到,在getInfo()中,我返回了从未

我不知道这是一个bug还是一个特性,但对于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"
    }
}
现在,这给了
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