2017-03-17 7 views
0

私は、オーバーロードされたメソッドでRunnablesまたはCallableをとるランナークラスを持っています。 runメソッドを実行する必要がラムダ式を使ってクラス内の特定のメソッドを実行する方法

class MyController { 
    public void run(Runnable command) { 
    } 

    public void run(Callable command) { 
    } 
} 

他のクラスは

controllerInstance.run(() -> {...}); 

がどのようにラムダ式ベースのコードは、(Runnableを)実行または実行(コーラブル)を呼び出すことが決定しないのですか?このデフォルトの動作を変更する方法はありますか?

+0

私は、第2のメソッド 'call()'の名前を変更することで明示的にすることをお勧めします。 名前付きのメソッドを使用する方法はありますが(下の回答を参照)、すべてがあまりエレガントでないコードにつながる傾向があります。 – lukens

答えて

1

必要なラムダの種類を決定するメソッドシグネチャです。 したがって、voidが返されるとき、ラムダメソッドはRunnableインターフェイスと一致します。 オブジェクトが返されるとき、ラムダメソッドはCallableインターフェイスと一致します。

import java.util.concurrent.Callable; 

class MyController { 
    public void run(Runnable command) { 
    System.out.println("Runnable"); 

    } 

    public void run(Callable command) { 
    System.out.println("Callable"); 
    } 

    public static void main(String [] args) { 
    MyController myController = new MyController(); 

    myController.run(() -> { return "String"; } ); 
    myController.run(() -> {}); 
    } 
} 

これが返されます。

Callable 
Runnable 
+0

「ラムダを指揮する方法」へのあなたの答えはラムダを使わないことです? – Andreas

+0

humm ...右。 :) – freedev

1

あなたは「タグ」が実装すべきかのインタフェースを示します鋳造表現、とラムダをすることができます。例えば:

controllerInstance.run((Runnable)() -> {...}); 

ちょうどRunnableはそうではないCallableが実際に解像度が考慮されている方法で、戻り値を持っていることに注意してください。私は、ラムダボディのブロックまたは式が値を返す限り、Callableオーバーロードが使用されることを発見しました。呼び出しが実際にあいまいである場合は、エラーが発生し、明示的キャストを使用できます。

2

あなたが値を返す場合は、java.lang.Runnablejava.util.concurrent.Callableに言及していると仮定すると、それは、Callableにマッチし、それが値を返さない場合、それはそう余分な資格を必要としない、Runnableと一致します。

controllerInstance.run(() -> { /*no return*/ }); // calls run(Runnable command) 
controllerInstance.run(() -> { return null; }); // calls run(Callable command) 

ただし、必要に応じて、キャストすることで問題を強制できます。

controllerInstance.run((Runnable)() -> { /*no return*/ }); // calls run(Runnable command) 
controllerInstance.run((Callable)() -> { return null; }); // calls run(Callable command) 
関連する問題