Closure equality

Neal Gafter neal at gafter.com
Tue May 20 07:17:19 PDT 2008


Yes, this is a specification issue.  I expect closures that don't capture
state to be statically allocated in a production-quality implementation, but
I don't expect the spec to promise what the scope of that allocation is.
So, for example, two Foo#bar() expressions written in separate translation
units might or might not end up being equal.  I expect findbugs will be
extended to complain about synchronizing on such things.

On Tue, May 20, 2008 at 7:06 AM, Mark Mahieu <mark at twistedbanana.demon.co.uk>
wrote:

> This might be more to do with the specification, but anyway...
>
> Equality of closure literals and method references in particular feels
> inconsistent with class and String literals, ie:
>
> Foo.class == Foo.class evaluates to true
> "Foo" == "Foo"  evaluates to true
> Foo#bar() == Foo#bar() evaluates to false
>
> Yet, given:
>
> class Foo {
>
> void foo() {
> {=>} barRef = Foo#bar();
> }
>
> static void bar() {
> // ...
> }
> }
>
> multiple invocations of the method foo(), be they sequential or
> concurrent, *will* see the same (statically allocated) instance assigned
> to barRef.  I think this could cause some confusion - it surprised me
> anyway, until I ran javap and saw that the prototype is already statically
> allocating some closures which don't capture state (not all of them though:
> if I change the method reference in the above class to be 'this#bar()' it's
> no longer statically allocated, but I think it could be).
>
> FindBugs specifically looks for synchronization on String constants, and I
> can imagine synchronization on method references causing similar issues if
> the rules aren't obvious:
> http://findbugs.sourceforge.net/bugDescriptions.html#DL_SYNCHRONIZATION_ON_SHARED_CONSTANT
>
> Perhaps it would be least surprising if two method references which resolve
> to the same method are considered referentially equal, including when they
> are referenced by different classes.  Unfortunately I think that last point
> implies some kind of 'intern'-ing mechanism.
>
> Actually, synchronizing on closure literals / method references doesn't
> compile at the moment anyway (which looks superficially similar to the
> closure literals vs instanceof bug I mentioned a couple of days ago).
>
>
> public class SynchClosure {
>
>     public static void main(String[] args) {
>
>         synchronized({=>}) { }
>
>         synchronized(SynchClosure#foo()) { }
>     }
>
>     static void foo() {
>     }
> }
>
>
> SynchClosure.java:5: unexpected type
> found   : { => void}
> required: reference
>         synchronized({=>}) { }
>         ^
> SynchClosure.java:7: unexpected type
> found   : { => void}
> required: reference
>         synchronized(SynchClosure#foo()) { }
>         ^
> 2 errors
>
>
>
> Regards,
>
> Mark
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20080520/25790ca2/attachment.html 


More information about the closures-dev mailing list