java - 匿名类中的 Groovy 脚本字段访问

标签 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() {
                println "Runnable1: ${test}";
            }
        }.run();
    }
}.run();

当从脚本中的匿名类访问它时,如 here ,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 放入类似 here 的函数中, Groovy 没有强制转换的问题,但是在内部的 Runnable 中找不到 Field:

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)

这可以通过重新定义像here 这样的字段来解决。 , 但此修复仅在函数内部有效

这是 Groovy 中的错误还是我只是违反了一些规则而 Groovy 只是缺少适当的异常?

最佳答案

如果调用匿名类并引用字段变量,则不需要 @Field 转换。

原因:
当脚本中的严格类型变量定义为 @Field 时,该变量(在编译时 [AST 转换])在该脚本中被视为私有(private)变量。因此缺少属性。

为了了解差异,只需从 Groovy 控制台在 AST 浏览器中可视化脚本并在两种情况下(不使用和使用 @Field)进行“语义分析”阶段,您会注意到该变量是 run() 的本地变量主脚本与分别在全局定义的相比。

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

详情摘自 AST browser

关于java - 匿名类中的 Groovy 脚本字段访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18725769/

相关文章:

javascript - 在 Struts Action 做一些计算后执行 javascript 函数

java - 如何将任务添加到 gradle 中的主要 'build' 任务

java - 这个实现会被称为匿名类吗?

Java 8 : Merge String[] and int[] into Object[] when verifying bytecode

java - 如何打印从用户输入开始并降序排列的字母金字塔?

java - 使用 Map 和 HashMap 作为声明类型的区别

java - 将 HTTP post 从 ruby​​ 转换为 java 或 groovy

java - 如何使用 Gradle 构建工具压缩受密码保护的文件夹

来自匿名方法的java引用 "this"

java - JavaFX 中使用事件的这些方法是否相同?