Saturday, August 8, 2009

Anonymous Inner Classes: A Poor Man's Closure?


Yesterday I had a discussion with a colleague about whether Java has closures or not. We both could immediately agree that, formally speaking, Java does not have them, but the part of the discussion that went on and on was about passing anonymous inner classes vs. passing around an anonymous function. I argued that the anonymous inner classes were a very poor substitute because a class has so much extra baggage, both conceptually and behaviorally. Classes understand and do all sorts of things that you don't care about when you are simply trying to pass along a little ol' function. Stuff like: inheritance, encapsulation, polymorphism. Worst of all, classes require lots of messy syntax. My colleague made an important point though: What else is a Java developer gonna do? When you are working in Java and you need something like a closure you've got no choice but to go for the anonymous inner class, the poor man's closure.

Google's Collection Framework is the best example I know of Java programmers making do with their poor man's closures. Here is a quick bit of sample code I created that demonstrates applying a function to every element of a list (Sorry you can't see my generics. I can't seem to escape properly for html):


import com.google.common.collect.Lists;
import com.google.common.base.Function;
import java.util.ArrayList;
import java.util.List;
public class PoorMansClosure{
public static void main(String[] args){
//Demonstrate something similar to the map function on a collection in ruby
ArrayList strings = Lists.newArrayList("feeling", "bad");
Function upcase = new Function(){
public String apply(String from){
return from.toUpperCase();
}
};
List upperCaseStrings = Lists.transform(strings, upcase);
for(String val : upperCaseStrings){
System.out.println(val);
}
}
}

Martin Fowler has a nice article about how closures naturally compliment collections. Here is a quick bit of ruby to demonstrate that.

class Closure
def demonstrate
strings = ["feeling", "good"]
upper_case_strings = strings.map{|elem| elem.upcase }
p upper_case_strings
end
end
Closure.new.demonstrate


In this example the closure frees us from the burden of specifying the names and signatures for both class and method and we simply give the function that maps to upper case without the noise. There have been rumblings in the Java world for some time that Java might someday support closures. Here's hoping that Java 7 will. If that does happen it will be interesting to see what they do to the collection framework. The existance of Google's collection framework is proof that the standard Java framework has major drawbacks. I think a major rewrite will be in order.