Java 8 lambda Void引数


Answers

何もしなければSupplier使用してください。

何も返さない場合はConsumer使用します。

実行しない場合はRunnable使用してください。

Question

私がJava 8で次の機能インタフェースを持っているとしましょう:

interface Action<T, U> {
   U execute(T t);
}

また、引数や戻り値のないアクションが必要な場合もあります。 だから私は次のようなことを書いています:

Action<Void, Void> a = () -> { System.out.println("Do nothing!"); };

しかし、それは私にコンパイルエラーを与える、私はそれを書く必要があります

Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;};

どちらが醜いですか? Void型のパラメータを取り除く方法はありますか?




特別なケースのためのサブインターフェースを作成することができます:

interface Command extends Action<Void, Void> {
  default Void execute(Void v) {
    execute();
    return null;
  }
  void execute();
}

継承されたパラメータ化されたメソッドVoid execute(Void)をオーバーライドするデフォルトのメソッドを使用して、より単純なメソッドvoid execute()呼び出しを委譲します。

その結果、使用する方がはるかに簡単です。

Command c = () -> System.out.println("Do nothing!");



あなたの例では関数定義が一致しないので、私はそれが可能だとは思わない。

ラムダ式は次のように正確に評価されます。

void action() { }

宣言は次のようになります

Void action(Void v) {
    //must return Void type.
}

たとえば、次のインターフェイスがある場合

public interface VoidInterface {
    public Void action(Void v);
}

互換性がある唯一の種類の関数(インスタンス化中)は次のようになります

new VoidInterface() {
    public Void action(Void v) {
        //do something
        return v;
    }
}

return文または引数がないと、コンパイラエラーが発生します。

したがって、引数をとり、それを返す関数を宣言すると、上記のどちらにも該当しない関数に変換することは不可能と思う。




メソッドの参照のためにどの関数インタフェースを使うことができるかを参照するために、メソッドは値をスローまたは返す。

void notReturnsNotThrows() {};
void notReturnsThrows() throws Exception {}
String returnsNotThrows() { return ""; }
String returnsThrows() throws Exception { return ""; }

{
    Runnable r1 = this::notReturnsNotThrows; //ok
    Runnable r2 = this::notReturnsThrows; //error
    Runnable r3 = this::returnsNotThrows; //ok
    Runnable r4 = this::returnsThrows; //error

    Callable c1 = this::notReturnsNotThrows; //error
    Callable c2 = this::notReturnsThrows; //error
    Callable c3 = this::returnsNotThrows; //ok
    Callable c4 = this::returnsThrows; //ok

}


interface VoidCallableExtendsCallable extends Callable<Void> {
    @Override
    Void call() throws Exception;
}

interface VoidCallable {
    void call() throws Exception;
}

{
    VoidCallableExtendsCallable vcec1 = this::notReturnsNotThrows; //error
    VoidCallableExtendsCallable vcec2 = this::notReturnsThrows; //error
    VoidCallableExtendsCallable vcec3 = this::returnsNotThrows; //error
    VoidCallableExtendsCallable vcec4 = this::returnsThrows; //error

    VoidCallable vc1 = this::notReturnsNotThrows; //ok
    VoidCallable vc2 = this::notReturnsThrows; //ok
    VoidCallable vc3 = this::returnsNotThrows; //ok
    VoidCallable vc4 = this::returnsThrows; //ok
}