Return CompletableFuture<Void> 或 CompletableFuture<?>?
Return CompletableFuture<Void> or CompletableFuture<?>?
我想编写一个 return 是 CompletableFuture
的异步方法。 future 的唯一目的是跟踪方法何时完成,而不是其结果。 returnCompletableFuture<Void>
好还是CompletableFuture<?>
好?有理由偏爱其中之一,还是可以互换?
CompletableFuture
本身 returns CompletableFuture<Void>
来自它的许多方法。
java.nio
在 AsynchronousSocketChannel
中有一个 Future<Void>
:Future<Void> connect(SocketAddress remote)
.
- 另一方面,
java.util.concurrent
类 喜欢 ExecutorService
and ScheduledExecutorService
return Future<?>
:例如 Future<?> submit(Runnable task)
.
请注意,我只询问 return 类型,而不是参数列表、变量声明或其他上下文。
Would it be better to return CompletableFuture<Void> or
CompletableFuture<?>
Is there a reason to prefer one or the other, or are they
interchangeable?
代码可能会影响三种上下文:
- 运行时 - 泛型对其没有影响。
- 编译 - 我无法想象某些方法会接受
Future<Void>
但不会接受 Future<?>
. 的情况
- 开发 - 如果
Future
的结果没有意义,那么最好通过声明向用户说明。
所以Future<Void>
更可取。
看一下CompletableFuture
API你会发现CompletableFuture<Void>
是用了一些有副作用的方法,结果得不到(因为它不存在) ), 例如:
CompletableFuture.runAsync(Runnable runnable);
return在这里输入 CompletableFuture<Object>
会令人困惑,因为实际上没有结果,我们只关心完成。采用 Consumers
和 Runnables
return CompletableFuture<Void>
的方法,例如:thenAccept
、thenAcceptAsync
。 Consumer
和 Runnable
通常用于副作用。
Void
的另一个用例是当您真的不知道结果时。例如:CompletableFuture.allOf
,传过来的list可能是一个CompletableFuture,来源于一个Runnable,所以我们拿不到结果。
综上所述,CompletableFuture<Void>
只有在你没有其他选择的情况下才是好的,如果你能return结果那么请去吧,来电者可能会选择放弃如果他们不感兴趣。你说你只对完成感兴趣,那么是的,CompletableFuture<Void>
可以完成这项工作,但是如果你的 API 用户知道 CompletableFuture<T>
是一个选项而你只是代表他们决定他们永远不需要结果。
最好用CompletableFuture<Void>
.
According to this answer found by Sotirios Delimanolis,Future<?>
是一个小 API 缺陷。在 Java 6 中,submit()
方法在内部使用了 Future<Object>
,因此它的 return 类型被设置为 Future<?>
。在 Java 7 中,实现更改为在内部使用 Future<Void>
,但更改 API 为时已晚,因此 return 值保持为 Future<?>
。
较新的 Java API 使用 Future<Void>
和 CompletableFuture<Void>
。这些是我们应该效仿的例子。
合适的类型取决于它的语义。所有列出的选项都承诺发出完成信号,并可能异步 return 异常。
CompletableFuture<Void>
:Void
告诉用户没有预期的结果。
CompletableFuture<?>
?
表示包含值的类型未定义,可以传递任何值。
CompletableFuture
class 从 CompletionStage
继承了几个方便的方法。但它确实也允许你的方法的调用者触发未来的完成,这似乎是错误的,因为你的方法负责发出它自己完成的信号。还有一个 cancel(...)
方法,它在 CompletableFuture
的默认实现中毫无意义,因为它不会取消执行。
Future<Void>
:Void
告诉用户没有预期的结果。
Future<?>
?
表示包含值的类型未定义,因为任何值都可以传递。
Future
缺少 CompletionStage
中的便捷方法。它不允许触发未来的完成,但可以取消执行。
下一个选项是CompletionStage<Void>
:
CompletionStage<Void>
:Void
告诉用户没有预期的结果。存在绑定处理程序的便捷方法,但 cancel(...)
方法不存在。您的方法的调用者无法触发 CompletionStage
. 的完成
<CancellableFuture extends Future<Void> & CompletionStage<Void>>
:来自 Future<Void>
和 CompletionStage<Void>
的一组方法。它表明没有结果,存在便捷方法以及取消选项。您的方法的调用者无法触发 CompletionStage
. 的完成
缺少 cancel(...)
方法可能适合或不适合您的情况。因此,如果您不需要取消,我建议使用 CompletionStage<Void>
,如果您需要取消执行的选项,则使用 <CancellableFuture extends Future<Void> & CompletionStage<Void>>
。如果您选择 <CancellableFuture extends Future<Void> & CompletionStage<Void>>
,您可能想自己创建一个继承自 Future<Void>
和 CompletionStage<Void>
的接口,以用作 return 类型,而不是将 long 类型交集直接放在您的方法声明。
您应该避免使用已声明的 return 类型 CompletableFuture
returning,因为调用者有可能触发 future 的完成。故意这样做会导致代码混乱和意外挂起,因为不清楚哪个代码负责触发完成。使用提到的更受限制的类型之一,让类型系统防止您的方法的调用者无意中触发完成。
我想编写一个 return 是 CompletableFuture
的异步方法。 future 的唯一目的是跟踪方法何时完成,而不是其结果。 returnCompletableFuture<Void>
好还是CompletableFuture<?>
好?有理由偏爱其中之一,还是可以互换?
CompletableFuture
本身 returnsCompletableFuture<Void>
来自它的许多方法。java.nio
在AsynchronousSocketChannel
中有一个Future<Void>
:Future<Void> connect(SocketAddress remote)
.- 另一方面,
java.util.concurrent
类 喜欢ExecutorService
andScheduledExecutorService
returnFuture<?>
:例如Future<?> submit(Runnable task)
.
请注意,我只询问 return 类型,而不是参数列表、变量声明或其他上下文。
Would it be better to return CompletableFuture<Void> or CompletableFuture<?>
Is there a reason to prefer one or the other, or are they interchangeable?
代码可能会影响三种上下文:
- 运行时 - 泛型对其没有影响。
- 编译 - 我无法想象某些方法会接受
Future<Void>
但不会接受Future<?>
. 的情况
- 开发 - 如果
Future
的结果没有意义,那么最好通过声明向用户说明。
所以Future<Void>
更可取。
看一下CompletableFuture
API你会发现CompletableFuture<Void>
是用了一些有副作用的方法,结果得不到(因为它不存在) ), 例如:
CompletableFuture.runAsync(Runnable runnable);
return在这里输入 CompletableFuture<Object>
会令人困惑,因为实际上没有结果,我们只关心完成。采用 Consumers
和 Runnables
return CompletableFuture<Void>
的方法,例如:thenAccept
、thenAcceptAsync
。 Consumer
和 Runnable
通常用于副作用。
Void
的另一个用例是当您真的不知道结果时。例如:CompletableFuture.allOf
,传过来的list可能是一个CompletableFuture,来源于一个Runnable,所以我们拿不到结果。
综上所述,CompletableFuture<Void>
只有在你没有其他选择的情况下才是好的,如果你能return结果那么请去吧,来电者可能会选择放弃如果他们不感兴趣。你说你只对完成感兴趣,那么是的,CompletableFuture<Void>
可以完成这项工作,但是如果你的 API 用户知道 CompletableFuture<T>
是一个选项而你只是代表他们决定他们永远不需要结果。
最好用CompletableFuture<Void>
.
According to this answer found by Sotirios Delimanolis,Future<?>
是一个小 API 缺陷。在 Java 6 中,submit()
方法在内部使用了 Future<Object>
,因此它的 return 类型被设置为 Future<?>
。在 Java 7 中,实现更改为在内部使用 Future<Void>
,但更改 API 为时已晚,因此 return 值保持为 Future<?>
。
较新的 Java API 使用 Future<Void>
和 CompletableFuture<Void>
。这些是我们应该效仿的例子。
合适的类型取决于它的语义。所有列出的选项都承诺发出完成信号,并可能异步 return 异常。
CompletableFuture<Void>
:Void
告诉用户没有预期的结果。CompletableFuture<?>
?
表示包含值的类型未定义,可以传递任何值。
CompletableFuture
class 从 CompletionStage
继承了几个方便的方法。但它确实也允许你的方法的调用者触发未来的完成,这似乎是错误的,因为你的方法负责发出它自己完成的信号。还有一个 cancel(...)
方法,它在 CompletableFuture
的默认实现中毫无意义,因为它不会取消执行。
Future<Void>
:Void
告诉用户没有预期的结果。Future<?>
?
表示包含值的类型未定义,因为任何值都可以传递。
Future
缺少 CompletionStage
中的便捷方法。它不允许触发未来的完成,但可以取消执行。
下一个选项是CompletionStage<Void>
:
CompletionStage<Void>
:Void
告诉用户没有预期的结果。存在绑定处理程序的便捷方法,但cancel(...)
方法不存在。您的方法的调用者无法触发CompletionStage
. 的完成
<CancellableFuture extends Future<Void> & CompletionStage<Void>>
:来自Future<Void>
和CompletionStage<Void>
的一组方法。它表明没有结果,存在便捷方法以及取消选项。您的方法的调用者无法触发CompletionStage
. 的完成
缺少 cancel(...)
方法可能适合或不适合您的情况。因此,如果您不需要取消,我建议使用 CompletionStage<Void>
,如果您需要取消执行的选项,则使用 <CancellableFuture extends Future<Void> & CompletionStage<Void>>
。如果您选择 <CancellableFuture extends Future<Void> & CompletionStage<Void>>
,您可能想自己创建一个继承自 Future<Void>
和 CompletionStage<Void>
的接口,以用作 return 类型,而不是将 long 类型交集直接放在您的方法声明。
您应该避免使用已声明的 return 类型 CompletableFuture
returning,因为调用者有可能触发 future 的完成。故意这样做会导致代码混乱和意外挂起,因为不清楚哪个代码负责触发完成。使用提到的更受限制的类型之一,让类型系统防止您的方法的调用者无意中触发完成。