2012-04-03 24 views
16

Apple Objective-C言語の機能は本当に便利です。メソッドの引数としてコードブロックを渡すことができます。ObjectiveC blocks Java equivalent

私はJavaでもそうしたいと思います。 のような何か:

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

のでmyManagerオブジェクトがにStartTransaction()とENDTRANSACTION()メソッドの間に私のコードを実行します。

Javaで取得する方法はありますか?

+0

簡単な答えは「ノー」、Javaでそのようには機能はありませんです。 –

+0

2014年、答えは「ちょうどRunnableを使用する」と思われます。 – Fattie

答えて

40

残念ながら、Javaはこれをサポートしていません。しかし、匿名クラスでも同様の機能を得ることができます。

は、最初は、インターフェイスを定義し、これを実行するには、次の

interface TransactionAction { 
    public void perform(); 
} 

doSomethingInTransactionは、引数としてTransactionActionを取るように定義する必要があります。

その後、あなたはそれを呼び出すときに、このか:

myManager.doSomethingInTransaction(new TransactionAction() { 
    public void perform() { 
     dao.save(); 
    } 
}); 
+1

この例は、 'do'がキーワードであるため動作しません。 – Landei

+0

ええ、ただ気づいた。 – Taymon

+0

ありがとうございます。これ以上はっきりすることはありません! :) –

11

ありませんが、これは(まだ)は、Javaには存在しません。行います、単一の方法で

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

または任意のインターフェイス:この問題を回避するには、Runnableインタフェースを使用することです。

+0

これが最適なソリューションです! –

3

あなたは関数が

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

のように呼ばれることだろうが、あなたのコードがアクセスできるようにしたい場合

someType functionToBeExecuted(CodeBlock cb) { 
    ... 
} 

ようになり

interface CodeBlock { 
    void execute(); 
} 

のようなインターフェイスを使用することができます変数やフィールドはより特殊化されます。新しいオブジェクトのため、パフォーマンスもこのように低くなります。

2

これは、ラムダ式使用してJava 8で可能になりました:doSomethingInTransactionの実装ではRunnableパラメータ、または任意の他の単一の方法を受け入れるべき

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

:簡潔

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

以上一致するメソッドシグネチャを持つインターフェイス。

現在地Oracleのドキュメントを見つけることができます:https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

+2

これは 'myManager.doSomethingInTransaction(dao :: save);に単純化することもできます。 – Palle