我想尝试一下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
的方法参考和apply
类的方法Test
相同
为什么第一个不起作用?
顺便说一句
为什么这个也是正确的
CompletableFuture.supplyAsync(CompletableFutureTests::name)
.thenApplyAsync(CompletableFutureTests::surname)
.thenApply(CompletableFutureTests::world)
.thenAccept(CompletableFutureTests::surname);
(我将方法姓氏的方法引用传递给thenAccept
但thenAccept
应该将Consumer
作为arg)
答案 0 :(得分:1)
为什么第一个不起作用?
它不起作用,因为 consumer()方法不是静态的;您提供了一个需要静态方法的实例方法。使它成为一个静态方法,您的代码将起作用:
private static void consumer(String str) {
System.out.println("str");
}
BTW为什么这个也是正确的
(即为什么你能成功提供一个方法引用,当所需参数是一个没有返回值的Consumer时返回一个值?)
您的问题与此SO问题重复:Why does a Java method reference with return type match the Consumer interface?
请特别注意Brian Goetz的这些评论:
以下是此设计决策的基础:Java允许您调用方法并忽略返回值(方法调用表达式作为语句)。由于我们在调用时允许这样做,所以在将方法适用于参数兼容但功能接口无效返回的功能接口时,我们也允许这样做。
另请注意,我们将进行其他修改(装箱,拆箱)以使lambda的形状与功能界面的预期形状相匹配。忽略返回值只是其中一种调整。
...设计决策的基础是允许将方法调整为功能接口,就像调用方法一样,即可以调用每个返回值的方法并忽略返回的值。