为什么需要明确声明 lambda 是 Consumer 才能使用 andThen 方法?

Pet*_*rov 4 java lambda functional-programming java-8

当我尝试使用两个 void 方法的函数组合时,我遇到了一个奇怪的(对我来说)行为。我写了一个简单的例子来说明这个问题:

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 {

    }

}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译第一个解决方案时,它在 andThen 调用之前显示“')'预期”。

当我明确地说这是消费者时,代码已编译并且按预期工作。

谁能向我解释为什么会发生这种情况,以及是否有另一种方法可以使用 Java 8 进行 void 方法的函数组合?

Eug*_*ene 5

让我们把这个变得更简单:

 private static boolean test(String input){
       return input.equals("123");
 }

 Predicate<String> predicate = YourClass::test;
 Function<String, Boolean> function = YourClass::test;
Run Code Online (Sandbox Code Playgroud)

因此,方法引用是一个表达式(例如泛型),它们取决于使用它们的上下文。因此,您的Startup::doSomething方法引用可以是任何 @FunctionalInterface符合该方法的方法。在您看来,Consumer在这种情况下它是 a,但对于编译器来说这是一个不同的故事。