なぜ明示的にラムダがandThenメソッドを使用する消費者であると言うことが必要でしょうか?

ペタルペトロフ:

私は2つの空のメソッドと関数合成を使用しようとしていたとき、私は奇妙な(私にとっては)行動に直面してきました。私はこの問題を説明するために簡単な例を書きました:

public class Startup {

    public static void main(String[] args) {

        List<Foo> foos = new ArrayList<>();

        // 1) Does not compile
        foos.forEach(Startup::doSomething1.andThen(Startup::doSomething2));

        Consumer<Foo> doSomething1 = Startup::doSomething1;
        Consumer<Foo> doSomething2 = Startup::doSomething2;

        // 2) Works as expected 
        foos.forEach(doSomething1.andThen(doSomething2));

    }

    public static void doSomething1(Foo foo) {

    }

    public static void doSomething2(Foo foo) {

    }

    public static class Foo {

    }

}

私はそれが言う最初のソリューションをコンパイルしようとするとandThen呼び出しの前に「『)』予想」。

私は明示的に言うとき、これはコードがコンパイルされた消費者であり、期待どおりに動作します。

誰もが私がなぜ起こっているこのおよびJava 8でのボイドメソッドの関数合成を行うための別の方法があるに説明できますか?

akortex91:

これは、ラムダのJava inferes、変換して検出種類の方法に関係しています。上記のコメントで述べたように、への変換がConsumer<Foo>行われ、まだコンパイラはこれがあることを知っていないことを意味していないConsumerので、あなたがチェーンことができandThen()、その後。

明示的にこれをキャストConsumerし、適切に括弧を使用することで、所望の効果を達成できるようになります。

List<Foo> foos = new ArrayList<>();
foos.forEach(((Consumer<Foo>) Null::doSomething).andThen(Null::doSomething2));

私はあなたがそれを周りいじるならば、あなたはタイプの証人を使用して、同じ動作を実現することができますね私は、彼らが所望の結果を達成できるかどうかを確認してください100%ではないです。

私はこれに気づいた最初の時間は同じ挙動を示すことがチェーンのコンパレータを使用していました。そのことについて、オンライン検索を行うと、あなたにどのようにこの作品に関するいくつかのより多くの複雑な詳細が表示されます。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=184620&siteId=1