18

There's a feature of the Apple Objective-C language which is really useful to me: I can pass code blocks as argument in methods.

I'd like to do that in Java, too. Something like:

myManager.doSomethingInTransaction(function() {
   dao.save();  
});

So the myManager object will execute my code between a startTransaction() and a endTransaction() methods.

Is there a way to get that in Java?

jscs
  • 63,694
  • 13
  • 151
  • 195
Fabio B.
  • 9,138
  • 25
  • 105
  • 177

4 Answers4

43

Unfortunately, Java doesn't support this. But you can get similar functionality with anonymous classes.

To do so, first you define an interface:

interface TransactionAction {
    public void perform();
}

doSomethingInTransaction should then be defined to take a TransactionAction as an argument.

Then, when you call it, do this:

myManager.doSomethingInTransaction(new TransactionAction() {
    public void perform() {
        dao.save();
    }
});
Taymon
  • 24,950
  • 9
  • 62
  • 84
13

No this does not exist in Java (yet). A workaround is to use the Runnable interface:

myManager.doSomethingInTransaction(new Runnable() {
    public void run() {
        dao.save();  
    }
});

or any interface with a single method will do.

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
4

This is now possible in Java 8 using a lambda expression:

myManager.doSomethingInTransaction(() -> {
    dao.save();  
});

Or more tersely:

myManager.doSomethingInTransaction(() -> dao.save());

Your implementation of doSomethingInTransaction should accept a Runnable parameter, or any other single-method interface with a matching method signature.

You can find Oracle's documentation here: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

4

you can use an Interface like

interface CodeBlock {
    void execute();
}

the function would look like

someType functionToBeExecuted(CodeBlock cb) {
    ...
}

it would be called like

functionToBeExecuted(new CodeBlock() {
   void execute() {
       // blah
   }
});

But if your code should be able to access variables or fields in will be more specialized. Also performance will be lower this way because of the new objects.