[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bindings and assignments (was: Re: continuations)



David B. Tucker wrote:
> Out of curiosity, does anyone know why Java only allows final variables
> to be referenced from within anonymous classes?

Yeah. It's stupid. Java doesn't have true lexical closures. All Java does 
is copy those "closed over" variables/params BY VALUE into the inner class. 
And to ensure that Java programmers don't get confused when they change one 
of these "closed over" variables but noticed that it doesn't change the 
copied variable, the variables are FORCED to be final. That way you can't 
change them.

(NB: when I say "pass by value" in Java I mean that a primitive type is 
passed by value, and that a reference to an object has the *referenced* 
passed by value; not the object passed by value).

Consider this anon inner class:
----
class Foo {
public Runnable foo(final int i) {
    final double z = 1.0;
    Runnable retval = new Runnable() {
        public void run() {
            System.out.println("i = " + i);
            System.out.println("z = " + z);
        }
    };
    return retval;
}
}
----

It is just syntactic sugar. The compiler turns it into this (notice how the 
compiler folded the constant z... I wasn't expecting that):

----
class Foo$1
    implements Runnable
{

    Foo$1(Foo this$0, int val$i)
    {
        this.this$0 = this$0;
        this.val$i = val$i;
    }

    public void run()
    {
        System.out.println("i = " + val$i);
        System.out.println("z = 1.0");
    }

    private final int val$i; /* synthetic field */
    private final Foo this$0; /* synthetic field */
}

class Foo {
public Runnable foo(int i)
{
    double z = 1.0D;
    Runnable retval = new Foo$1(this, i);
    return retval;
}
}

----