【问题标题】:CompletableFutures strange behavior with callbacksCompletableFutures 回调的奇怪行为
【发布时间】:2018-02-12 09:32:51
【问题描述】:

我想试验 CompletableFutures 的能力,为此我创建了简单的类 CompletableFutureTests

这是我的方法:

private static String name() {
    System.out.println("Name");
    return "ALmas";
}

@SneakyThrows(InterruptedException.class)
private static String surname(String name) {
    Thread.sleep(2000);
    System.out.println("sur");
    return name+" Abdrazak";
}

private static String world(String name) {
    System.out.println("world");
    return name + " hello";
}

private void consumer(String str){
    System.out.println("str");
}

private static String onExc(Exception name) {
    return "on exception";
}

及用法

CompletableFuture.supplyAsync(CompletableFutureTests::name)
                         .thenApplyAsync(CompletableFutureTests::surname)
                         .thenApply(CompletableFutureTests::world)
                         .thenAccept(CompletableFutureTests::consumer);

这段代码把我扔了

RuntimeException: Uncompilable source code - Erroneous sym type: java.util.concurrent.CompletableFuture.thenAccept

由于这条线

.thenAccept(CompletableFutureTests::consumer)

当我用新类替换它时

private static class Test implements Consumer<String>{

        @Override
        public void accept(String t) {
           System.out.println(t);
        }
        }

    }

CompletableFuture.supplyAsync(CompletableFutureTests::name)
                             .thenApplyAsync(CompletableFutureTests::surname)
                             .thenApply(CompletableFutureTests::world)
                             .thenAccept(new Test());

它按方面工作。如您所见,对方法consumer 的方法引用和Test 类中的方法apply 是相同的

为什么第一个不起作用?

顺便说一句

为什么这个也是正确的

CompletableFuture.supplyAsync(CompletableFutureTests::name)
                             .thenApplyAsync(CompletableFutureTests::surname)
                             .thenApply(CompletableFutureTests::world)
                             .thenAccept(CompletableFutureTests::surname);

(我将方法引用传递给thenAccept,但thenAccept 应该将Consumer 作为参数)

【问题讨论】:

    标签: java completable-future


    【解决方案1】:

    为什么第一个不起作用?

    它不起作用,因为您的 consumer() 方法不是静态的;您正在提供需要静态方法的实例方法。让它成为一个静态方法,你的代码就可以工作了:

    private static void consumer(String str) {
        System.out.println("str");
    }
    

    顺便说一句,为什么这个也是正确的

    (即当需要的参数是没有返回值的消费者时,为什么你可以成功提供返回值的方法引用?)

    您的问题与此 SO 问题重复:Why does a Java method reference with return type match the Consumer interface?

    特别注意来自Brian Goetz的这些cmets:

    这是此设计决策的基础:Java 允许您调用方法并忽略返回值(作为语句的方法调用表达式)。由于我们在调用时允许这样做,因此在将方法调整为参数兼容但函数接口返回 void 的函数式接口时也允许这样做。

    还要注意,我们将进行其他调整(装箱、拆箱)以使 lambda 的形状与功能接口的预期形状相匹配。忽略返回值只是其中一种适应方式。

    另见this answer from Holger:

    ...设计决策的基础是允许将方法适应功能接口,就像调用方法一样,即可以调用每个返回值的方法并忽略返回值。 em>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多