Java 匿名类中的GroovyScript字段访问

Java 匿名类中的GroovyScript字段访问,java,groovy,anonymous-class,Java,Groovy,Anonymous Class,在Groovy 2.1.6脚本中,我定义了一个字段: import groovy.transform.Field @Field String test = "abc"; println "Script: ${test}"; def run = new Runnable() { void run() { println "Runnable0: ${test}"; new Runnable() { void run() {

在Groovy 2.1.6脚本中,我定义了一个字段:

import groovy.transform.Field
@Field String test = "abc";

println "Script: ${test}";
def run = new Runnable() {
    void run() {
        println "Runnable0: ${test}";
        new Runnable() {
            void run() {
                println "Runnable1: ${test}";
            }
        }.run();
    }
}.run();
当从脚本(如)中的匿名类访问它时,Groovy似乎试图将此字段强制转换为引用,并在定义Runnable后立即抛出以下异常:

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'abc' with class 'java.lang.String' to class 'groovy.lang.Reference'
    at bug1.run(bug1:5)
此外,如果我将匿名Runnable放在函数中,比如Groovy在强制转换方面没有问题,但在内部Runnable中找不到字段:

groovy.lang.MissingFieldException: No such field: test for class: bug2$1
    at bug2$1.this$dist$get$1(bug2.groovy)
    at bug2$1$2.propertyMissing(bug2.groovy)
    at bug2$1$2.run(bug2.groovy:14)
    at java_lang_Runnable$run.call(Unknown Source)
    at bug2$1.run(bug2.groovy:12)
    at java_lang_Runnable$run.call(Unknown Source)
    at bug2.fun(bug2.groovy:9)
    at bug2.run(bug2.groovy:5)
这可以通过重新定义字段来解决,如 ,但此修复程序仅在函数内部工作


这是Groovy中的一个bug,还是我违反了一些规则,Groovy只缺少适当的异常?

在调用匿名类并引用字段变量的情况下,不需要进行
@Field
转换

原因:
当脚本中的严格类型变量定义为
@Field
时,该变量(在编译时[AST transformed])在该脚本中被视为私有变量。因此,财产失踪

为了实现这一差异,只需从Groovy控制台在AST browser中可视化脚本,并在这两种情况下(不使用@Field和使用@Field)经历“语义分析”阶段,您就会注意到,与分别全局定义的变量相比,主脚本的
run()
是局部变量

推论
另一方面,
@Field
转换在同一脚本内的方法中使用严格类型变量时非常有用,因为如果没有
@Field
,该字段将在脚本的
run()
方法中声明为局部变量,因此其他方法不可见


有关详细信息,请参阅的摘录。

由于Groovy闭包已经可以运行了,您可以执行以下操作:

import groovy.transform.Field
@Field String test = "abc";

println "Script: ${test}";
{ -> 
    println "Runnable0: ${test}";
    { -> 
        println "Runnable1: ${test}"
    }.run()
}.run()
哪个有效