Why is necessary to explicitly say a lambda is Consumer to use andThen method?

Petar Petrov :

I've faced a strange(for me) behavior when I was trying to use function composition with two void methods. I've written a simple example to illustrate the problem :

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 {

    }

}

When I try to compile the first solution it says "')' expected" before andThen call.

When I explicitly say this are Consumers the code is compiled and it works as expected.

Can anyone explain to my why this is happening and is there another way of doing function composition of void methods with Java 8?

akortex91 :

This has to do with the way Java inferes, converts and detects types in lambdas. As mentioned in a comment above, the conversion to Consumer<Foo> has not taken place yet meaning that the compiler does not know that this is a Consumer so that you can chain an andThen() afterwards.

Explicitly casting this to a Consumer and using parentheses properly will let you achieve the desired effect:

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

I guess if you fiddle around with it, you can achieve the same behavior using type witnesses but I am not 100% sure whether they can achieve the desired result.

First time I noticed this was using chained comparators which may exhibit the same behavior. Doing an online search about that will show you some more intricate details regarding how this works.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=73951&siteId=1
Recommended