UPDATE: new more comprehensive post on this subject: Closures with return values in Java.

In Java, closures/first-order functions are not a language feature. However, as everyone knows, you can effectively get a first-order function by using an anonymous subclass instead. Something like this:


class MyClosure {
void run() {} // override this
}
void doSomethingClosureLike() {
MyClosure closure = new MyClosure() { void run() { System.out.println("We're inside a closure!"); }};
runTheClosure(closure);
}
void runTheClosure(MyClosure closure) {
closure.run();
}
// will print We're inside a closure!

Anyway, it's simple enough, you pass the class instead of the function and there's a little extra verbage but it works!

Also you get closure-like functionality, because inside run() you can access variables from outwhere where you created it. E.g.:


void doSomethingCooler() {
final String myString = "Foo!";
MyClosure closure = new MyClosure() { void run() { System.out.println("The string is: " + myString); }};
runTheClosure(closure);
}
// will print The string is: Foo!

You can also access global variables that change over time, and the closure will use whatever is the current value WHEN THE CLOSURE RUNS.

There's just one small annoying thing, which is this particularly annoying compiler message:

local variable (WHATEVER) is accessed from within inner class; needs to be declared final

If you were do change myString to not be final, you'd get that error. Bummer. You could make myString a global variable and that would work, but that's stupid. There is a better way. Try this: UPDATE: This doesn't work, see new version at the bottom, thanks commenter the.d-stro.

void doSomethingCooler() {
String myString = "Foo!";
final String myStringFinal = myString;
myString.concat(" Bar!");
  MyClosure closure = new MyClosure() { void run() { System.out.println("The string is:" + myStringFinal); }};
 runTheClosure(closure);
}
// will print Foo! Bar!

Now you can even change myString after you assign myStringFinal, because Java, although they say it doesn't use pointers, really does use pointers. I.e. it passes by reference. So, myStringFinal is actually just a reference to myString, and keeps pointing to it even when you change the contents of myString.

You can CHANGE it (like using concat()) but you CAN'T reassign it. That will break the pointers. It makes sense if you think about it -- myString will have a new memory address, and myStringFinal will still be pointing to the old memory address (and the old string value). So, this won't work:

myString = "won't work"; // breaks myStringFinal

You can use this technique with any object (but not primitives like int).

UPDATE

The last source block is wrong because java Strings are immutable. Here's an example that will work as advertised:


void doSomethingCoolest() {
StringBuffer myString = new StringBuffer("Foo!");
final StringBuffer myStringFinal = myString;
myString.append(" Bar!");
MyClosure closure = new MyClosure() { void run() { System.out.println("The string is: " + myStringFinal); }};
runTheClosure(closure);
}
// will print The string is: Foo! Bar!