Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ObjectiveC blocks Java equivalent

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?

like image 938
Fabio B. Avatar asked Apr 03 '12 14:04

Fabio B.


4 Answers

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();
    }
});
like image 133
Taymon Avatar answered Nov 16 '22 17:11

Taymon


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.

like image 12
Guillaume Polet Avatar answered Nov 16 '22 19:11

Guillaume Polet


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

like image 2
John-Paul Gignac Avatar answered Nov 16 '22 19:11

John-Paul Gignac


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.

like image 3
joachim foobar Avatar answered Nov 16 '22 19:11

joachim foobar