[ https://issues.apache.org/jira/browse/GROOVY-8826?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16643108#comment-16643108 ]
Daniel Sun commented on GROOVY-8826: ------------------------------------ [~blackdrag] Thanks for your explanation in details. You are always my good mentor. The issue is more complex than I thought... Could you tell me why the following code get two {{2}}? In other words, why will the capatured {{i}} be changed even if the {{i}} is captured by closure. As far as I know, closure will store capatured variables in its instance fields. If we assign the value to field, even if i changed, field will hold the original value(i.e. 1). I do not understand why field's value will change while {{i}} changes(See the second following code snippet). Thanks in advance! {code:java} import java.util.ArrayList; import java.util.Arrays; public class Test { public static void main(String... args) { ArrayList<Runnable> closures = new ArrayList<>(); for (int i: new int[] {1, 2}) closures.add(() -> System.out.println(i)); for (Runnable closure: closures) closure.run(); } } {code} {code:java} Integer i = 1 Integer f = i // if we assign the value to f, even if i changed, f will hold the original value, i.e. 1 i = 2 println f // gets 1 {code} > Captured loop variables have surprising and Java-incompatible behavior > ---------------------------------------------------------------------- > > Key: GROOVY-8826 > URL: https://issues.apache.org/jira/browse/GROOVY-8826 > Project: Groovy > Issue Type: Bug > Affects Versions: 3.0.0-alpha-3 > Reporter: Роман Донченко > Priority: Major > > Consider this source: > {code:java} > import java.util.ArrayList; > import java.util.Arrays; > public class Test { > public static void main(String... args) { > ArrayList<Runnable> closures = new ArrayList<>(); > for (int i: new int[] {1, 2}) > closures.add(() -> System.out.println(i)); > for (Runnable closure: closures) > closure.run(); > } > } > {code} > If it's compiled as Java, the output is: > {code} > 1 > 2 > {code} > But if it's compiled as Groovy, the output is: > {code} > 2 > 2 > {code} > In other words, in Java each iteration gets a unique instance of the {{i}} > variable, which is captured in the corresponding closure, while in Groovy, > only one {{i}} variable exists and is captured into both closures. IMO, the > Groovy behavior is significantly less useful, and it would be nice if in 3.0 > it was changed to match Java. > Groovy also exhibits the same behavior with Groovy closures and > {{for(...in...)}} loops. I just used Java-compatible syntax for this example > in order to contrast Groovy and Java. -- This message was sent by Atlassian JIRA (v7.6.3#76005)