Closure equality
Mark Mahieu
mark at twistedbanana.demon.co.uk
Tue May 20 07:06:20 PDT 2008
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/5a63586f/attachment.html
More information about the closures-dev
mailing list