当前位置:  开发笔记 > 编程语言 > 正文

For循环在Groovy和Java中的工作方式不同

如何解决《For循环在Groovy和Java中的工作方式不同》经验,为你挑选了1个好方法。

请查看groovy中的以下代码段:

def static void main(String... args) {
    def arr = [1, 2, 3, 4, 5]
    for (int f in arr) {
        Thread.start { print f + ', '}
    }
}
Out: 2, 3, 5, 5, 5,

我对此输出感到惊讶.为什么"5"被多次打印?而且,在Java中运行等效代码的一切看起来都很好:

public static void main(String[] args) {
    int[] arr = new int[]{1, 2, 3, 4, 5};
    for (int f : arr) {
        new Thread(() -> { System.out.print(f + ", "); }).start();
    }
}
Out: 1, 5, 4, 3, 2,

任何人都可以解释为什么会这样吗?看起来groovy的问题在Closure实现中.但是,这种行为很奇怪.它是某种bug还是我没有意识到groovy是如何工作的?

谢谢!



1> Jerry101..:

Java闭包在创建时关闭不可变值f,而Groovy闭包关闭可变变量 f.

因此,一旦Groovy循环完成,f包含5和之后正在运行的线程将打印5.

Java闭包可以关闭一个最终或"有效最终"的变量引用,这意味着它除了名称之外都是最终的.请参阅Java 8:Lambdas,第1部分.这就是内部类可以做的事情以及一些有用的便利.

Groovy闭包是非常不同的对象,它们早于Java闭包.请参阅Groovy Closures,其中示例{ ++item }修改封闭范围中的变量.

Groovy将闭包定义为Closure类的实例.它使它与Java 8中的lambda表达式截然不同.委托是Groovy闭包中的一个关键概念,它在lambda中没有等价物.能够更改委托或更改闭包的委派策略使得在Groovy中设计漂亮的域特定语言(DSL)成为可能.

底线 Groovy旨在成为与Java具有最佳"阻抗匹配"的动态语言,但是现在Java已经有了lambdas,这两种语言仍然存在分歧.警告程序员.


Java没有闭包!Lambda是*不*封闭.Groovy和JavaScript都有闭包.Java没有.
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有