groovy - groovy 是否尊重闭包或匿名类外部定义的最终变量?

标签 groovy scope closures final

今天我在将一些java代码移植到groovy时发现了groovy的一些严重行为。

我们在 java 中经常做的事情:在循环中构建匿名类(例如用于操作)并引用在此类外部声明的最终变量。

如果你在 groovy 中运行这段代码,你会惊讶地得到的不是 1,2,3,4,5,6,7,8,9,而是 9,9,9,9,9,9 ,9,9,9。这意味着 groovy 不会将相应的最终变量 i 绑定(bind)到每个匿名类,而只是在执行时使用最后设置的值。

我在 groovy 文档中找不到此行为的任何原因。顺便说一句,如果我使用常规闭包而不是匿名类,我会得到相同的行为。

public static void main(String[] args) {
    int[] list = new int[10];
    for (int i = 0; i < 10; i++) {
        list[i] = i;
    }
    Runnable[] runnables = new Runnable[10];
    for (final int i : list) {
        runnables[i] = new Runnable() {
            @Override
            public void run() {
                System.out.println(i);
            }
        };
    }

    for (int i = 0; i < 10; i++) {
        runnables[i].run();
    }
}

最佳答案

奇怪...我会调查一下这是否是已知行为

同时,您可以通过在生成可运行对象的循环内声明另一个变量来解决这个问题,然后在可运行对象中使用它:

for (int i : list) {
    int k = i
    runnables[i] = new Runnable() {
        @Override
        public void run() {
            System.out.println(k);
        }
    }
}

或者通过使用 collect 生成 Runnable 数组:

Runnable[] runnables = list.collect { i -> 
    new Runnable() {
        @Override
        public void run() {
            System.out.println( i );
        }
    }
}

编辑

我四处询问,在类属性之外,Groovy 目前忽略了 final。不过,这是将来可能会添加的内容

关于groovy - groovy 是否尊重闭包或匿名类外部定义的最终变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17466895/

相关文章:

java - Guice 谜题 : Batch scoped Encapsulated Context

javascript - 'this'指的是什么?

javascript - 如何在循环中创建闭包并将其存储在变量中供以后执行

ios - self 已被封闭所俘获

java - 使用 Spring 3.0 将字节转换为类型,而无需更改应用程序(即将转换方法存储在 DB 中)

Java(或 Groovy)相当于 Scala 的 apply

groovy - Groovy中下划线的含义

c - 没有括号的 for 循环的绝对范围是什么?

javascript - 自动执行函数与对象中的闭包

java - 使用 Java 9 使 Ropeytask 崩溃