A stage of a possibly asynchronous computation, that performs an action or computes a value when another CompletionStage completes. A stage completes upon termination of its computation, but this may in turn trigger other dependent stages. The functionality defined in this interface takes only a few basic forms, which expand out to a larger set of methods to capture a range of usage styles:
stage.thenApply(x -> square(x))
.thenAccept(x -> System.out.print(x))
.thenRun(() -> System.out.println());
An additional form (compose) allows the construction of
computation pipelines from functions returning completion stages.
Any argument to a stage's computation is the outcome of a triggering stage's computation.
Executor). The execution
properties of default and async modes are specified by
CompletionStage implementations, not this interface. Methods with
explicit Executor arguments may have arbitrary execution
properties, and might not even support concurrent execution, but
are arranged for processing in a way that accommodates asynchrony.
handle and whenComplete) support unconditional computation
whether the triggering stage completed normally or exceptionally.
Method exceptionally supports computation
only when the triggering stage completes exceptionally, computing a
replacement result, similarly to the java catch keyword.
In all other cases, if a stage's computation terminates abruptly
with an (unchecked) exception or error, then all dependent stages
requiring its completion complete exceptionally as well, with a
CompletionException holding the exception as its cause. If
a stage is dependent on both of two stages, and both
complete exceptionally, then the CompletionException may correspond
to either one of these exceptions. If a stage is dependent on
either of two others, and only one of them completes
exceptionally, no guarantees are made about whether the dependent
stage completes normally or exceptionally. In the case of method
whenComplete, when the supplied action itself encounters an
exception, then the stage completes exceptionally with this
exception unless the source stage also completed exceptionally, in
which case the exceptional completion from the source stage is
given preference and propagated to the dependent stage.
All methods adhere to the above triggering, execution, and
exceptional completion specifications (which are not repeated in
individual method specifications). Additionally, while arguments
used to pass a completion result (that is, for parameters of type
T) for methods accepting them may be null, passing a null
value for any other parameter will result in a NullPointerException being thrown.
Method form handle is the most general way of
creating a continuation stage, unconditionally performing a
computation that is given both the result and exception (if any) of
the triggering CompletionStage, and computing an arbitrary result.
Method whenComplete is similar, but preserves
the result of the triggering stage instead of computing a new one.
Because a stage's normal result may be null, both methods
should have a computation structured thus:
(result, exception) -> {
if (exception == null) {
// triggering stage completed normally
else {
// triggering stage completed exceptionally
}
}}
This interface does not define methods for initially creating,
forcibly completing normally or exceptionally, probing completion
status or results, or awaiting completion of a stage.
Implementations of CompletionStage may provide means of achieving
such effects, as appropriate. Method toCompletableFuture
enables interoperability among different implementations of this
interface by providing a common conversion type.