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