The closure captures the 'i' variable. While one might think there is
one such unique variable for every loop, this isn't true; there's only
one 'i' variable, and at the end of each iteration, this one variable
is incremented. Therefore, what's going on here, is that we have a
closure that will print 'the current value of whatever 'i' holds, 'i'
being the one counter variable that exists in the scope of the first
for loop in this code'.

The value of that 'i', at the time the closures are actually run, is
always 3. It has in fact rolled out of scope for the main method; the
only remaining code block that is still referencing it are those 3
closures, and they certainly don't modify 'i', they just print it.
Therefore the value would obviously have to be equal for each 'print'
result. The 'fixed' version looks like this:

Runnable[] r = new Runnable[3];
for (int i = 0; i < 3; i++) {
    int temp = i;
    r[i] = #() {System.out.println(temp);};
}
for (int i = 0; i < 3; i++) r[i].run();

That *WOULD* print "123" as one might at casual glance expect.
However, note that in this particular case, the current status quo
closure proposal would "just work" because temp is effectively final
(making it actually final does not cause a compiler error. hence, it
is effectively final). Even in the mildest forms of the various
alternative plans for how to handle capturing variables, making 'temp'
final would always be legal, and making it final here does not require
any rewriting (other than stuffing one 'final' keyword in the above
snippet, of course).


The BGGA-esque full capture proposal *STILL* supports the notion of at
least generating a warning when sharing mutable local variables, which
can be removed by adding a "@Shared" annotation on the variable
declaration, and it does NOT let you capture variables declared in the
'declaration' part of a standard for loop. For those who thought
Osvaldo was not completely off-base in his earlier rant because he
insinuated Neal Gafter's proposal includes unfettered access to
outside mutables - there you go. He's lying.

On Jun 5, 8:05 am, "Vince O'Sullivan" <[email protected]> wrote:
> On Jun 2, 2:51 am, Reinier Zwitserloot <[email protected]> wrote:
>
> > NB: The 'final limitation' exists because of confusion. For example,
> > what does this print:
>
> > Runnable[] r = new Runnable[3];
> > for (int i = 0; i < 3; i++) r[i] = #() {System.out.print(i);};
> > for (int i = 0; i < 3; i++) r[i].run();
>
> > Looks like it ought to print "123", right? Nope. It would print "333".
> > Which is confusing.
>
> OK, I'm confused.  Explain, please.

-- 
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

Reply via email to