Effectively final effective?

John Nilsson john at milsson.nu
Fri Feb 26 12:32:45 PST 2010


On Fri, Feb 26, 2010 at 2:09 PM, Reinier Zwitserloot <
reinier at zwitserloot.com> wrote:

>  3. Variables accessed in closures will be silently copied, with the copy
> inside the closure being final, but the variable outside of it being
> mutable
> (but, as the closure gets a copy, any mutations don't show up in the
> closure). I've filed this away as crackpot, where it'll hopefully remain,
> as
> this is going to be very surprising to a lot of programmers and the only
> way
> this surprise is going to become obvious is after many hours spent
> debugging.
>

So before this is filed away, let me try again and explain why this is not
surprising and in fact the obvious behaviour.

The variable from the outside scope is "captured" at the time then the
lambda is created. In the same manner as any variable is carried into
another scope there and then.

int a = 1;
int b = 0;
{
  b = a;
}
a = 2;
//At this point b is expected to be 1, the value of a inside the block. It
is not expected that b has somehow been equated with the a variable just
because there is an equal sign implying that relation.

In the same manner you expect
for(Integer i : asList(1,2,3))
   aList.add(i);
to produce a list containing 1,2,3 and not a list containing 3 (the last
value of i)

So there is already a precedent for a semantic of capturing a value, not a
variable.


Now in ordinary blocks we are free to mutate variables from the outside
scope inside the inner scope. However as these blocks are exectued in the
same order as they are declared this is not a problem. With lambdas and
inner classes the definition is decoupled from the execution, which means
that the outer scope might not even exist at the time of execution. In
previous versions of Java this was solved only allowing final variables
inside inner classes. As they can't be mutated in either scope there is no
mutation order to care about.

So by continuing this line of reasoning, we simply continue to view them as
immutable inside the inner class/lambda but relax the requirement that they
are mutable in the defining scope. Thinking that it is the value that is
captured, not the variable.

BR,
John


More information about the lambda-dev mailing list