我想写一个返回a的异步方法CompletableFuture
.未来的唯一目的是跟踪方法何时完成,而不是结果.返回CompletableFuture
还是更好CompletableFuture>
?有理由偏爱其中一个,还是可以互换?
CompletableFuture
本身CompletableFuture
从它的许多方法返回.
java.nio
有一个Future
在AsynchronousSocketChannel
:Future
.
另一方面,java.util.concurrent
类ExecutorService
和ScheduledExecutorService
返回Future>
:例如,with Future> submit(Runnable task)
.
请注意,我只询问返回类型,而不是参数列表,变量声明或其他上下文.
最好用CompletableFuture
.
根据Sotirios Delimanolis发现的这个答案,Future>
是一个小的API漏洞.在Java 6中,该submit()
方法在Future
内部使用,因此其返回类型设置为Future>
.在Java 7中,实现更改为在Future
内部使用,但更改API为时已晚,因此返回值保持不变Future>
.
较新的Java API使用Future
和CompletableFuture
.这些是我们应该遵循的例子.
返回CompletableFuture
或CompletableFuture <?>会更好吗? 有理由偏爱其中一个,还是可以互换?
代码可能会影响三种上下文:
运行时 - 泛型对它没有任何影响.
编译 - 我无法想象某种方法会接受Future
但不接受的情况Future>
.
开发 - 如果Future
结果没有意义,那么通过声明向用户说明这一点是一个好习惯.
所以Future
更可取.
查看CompletableFuture
API,你会发现它CompletableFuture
与副作用一起用于无法获得结果的方法(因为它不存在),例如:
CompletableFuture.runAsync(Runnable runnable);
返回 CompletableFuture
这里会让人感到困惑,因为没有真正的结果,我们只关心完成.称取方法Consumers
和Runnables
返回CompletableFuture
,例如:thenAccept
,thenAcceptAsync
.Consumer
并且Runnable
通常用于副作用.
另一个用例Void
是当你真的不知道结果时.例如:CompletableFuture.allOf
,传递的列表可能是源自Runnable的CompletableFuture,因此我们无法获得结果.
说完所有这些,CompletableFuture
只有你没有其他选择才有用,如果你可以返回结果然后请去,如果他们不感兴趣,调用者可能会选择丢弃.你说你只对完成感兴趣,然后是的,CompletableFuture
会做这个工作,但如果他们知道这CompletableFuture
是一个选项而你的API用户会讨厌你,你只是代表他们决定他们永远不需要结果.
合适的类型取决于其语义。所有列出的选项均承诺完成信号,并可能异步返回异常。
CompletableFuture
:Void
告诉用户没有预期的结果。
CompletableFuture>
该?
装置包含值的类型在这个意义上,任何值可以交付不确定的。
在CompletableFuture
类继承几个方便的方法CompletionStage
。但是它也允许您的方法的调用者触发将来的完成,这似乎是错误的,因为您的方法负责自己完成的信号。还有一种cancel(...)
方法在默认实现中毫无意义,CompletableFuture
因为它不会取消执行。
Future
:Void
告诉用户没有预期的结果。
Future>
该?
装置包含值的类型在这个意义上,任何值可以交付不确定的。
Future
缺乏的便捷方法CompletionStage
。它不允许触发将来的完成,但可以取消执行。
下一个选项是CompletionStage
:
CompletionStage
:Void
告诉用户没有预期的结果。存在绑定处理程序的便捷方法,但cancel(...)
没有。方法的调用者无法触发的完成CompletionStage
。
:设置从方法Future
和CompletionStage
。它表明没有结果,提供了便捷方法以及取消选项。方法的调用者无法触发的完成CompletionStage
。
缺少该cancel(...)
方法可能适合您的情况。因此,我建议CompletionStage
您在不需要取消的情况下使用
,并在需要取消执行的选项时使用。如果选择
,则可能要自己创建一个继承Future
并CompletionStage
用作返回类型的接口,而不是将长类型交集直接放在方法声明中。
您应该避免使用声明的返回类型返回,CompletableFuture
因为调用者有可能触发将来的完成。这样做有意导致代码混乱,并且挂起令人惊讶的挂起,因为尚不清楚哪个代码负责触发完成。使用上述更受限制的类型之一,以使类型系统防止方法的调用者意外完成触发。