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

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



["David B. Tucker" <dbtucker@cs.brown.edu>]
> > I imagine, though I don't have statistical evidence, that the
> > requirement of declaring local variables to be final in order to
> > reference them within anonymous inner classes (closures) is almost
> > entirely unknown and unused in practice.
> 
> Out of curiosity, does anyone know why Java only allows final variables
> to be referenced from within anonymous classes?
> 

Yes... Suppose you wanted to implement anonymous inner classes without
real lexical closures. Access to fields is no problem, since they're
not lexically defined. They just work exactly as they do for normal
inner classes. Access to local variables (including parameters) can
easily be implemented by passing those variables into the new object
when it's constructed. However, this obviously breaks if those
variables are mutable. So, rather than implement all of this
"correctly", they just introduced a restriction that locals accessed
by anonymous inner classes have to be final.

I feel like I haven't explained this very well, and I hope it's
clear... Here's an example... Supposing an interface B, we can transform
this:

    class A
    {
        public void foo(int a)
        {
            int b;
            ...

            B bar = new B()
            {
                public int getValue()
                {
                    return a + b;
                }
            }
            ...

        }
    }

into:

    class A
    {
        public void foo(int a)
        {
            int b;
            ...
            B bar = new __new_B(a, b);
            ...
        }

        private class __new_B implements B
        {
            private final int __new_a;
            private final int __new_b;

            __new_symbol(int a, int b)
            {
                __new_a = a;
                __new_b = b;
            }

            public int getValue()
            {
                return __new_a + __new_b;
            }
        }
    }

but I think it should be obvious that this transformation is only safe if
a and b are final in A.foo().

This may be getting off-topic, but hey, you asked for it! Anyway, in
my opinion this is one of the largest warts on Java... 


Matt


-- 
Matt Hellige                  matt@immute.net
http://matt.immute.net