What is the difference between 'CompletionStage' and 'CompletableFuture'

20,495

Solution 1

CompletionStage<T> is an interface of which CompletableFuture<T> is the only current implementing class. By looking at the javadoc for CompletionStage<T>, you'll notice it provides methods for taking one CompletionStage<T> and transforming it into another CompletionStage<T>. However, the returned values by the CompletionStage<T> are actually themselves CompletabeFuture<T> objects.

So using CompletabeFuture<T> is kind of the same thing as using a CompletionStage<T> but the latter can be used as the base interface for possible new classes in the future as well as being a target type for many descending types just as we tend to do List<Integer> integerList = new ArrayList<>(); rather than ArrayList<Integer> integerList = new ArrayList<>();

Solution 2

A CompletableFuture is a CompletionStage. However, as its name suggests, it is

  • completable: It can be completed using complete or completeExceptionally.
  • a Future: You can use get method, etc. to get the result.

IMHO, in most APIs, like in your example, you should use CompletionStage, because

  • The implementation usually provides the mechanism to complete the stage. You don't need/want to expose methods like complete to the caller.
  • The caller is expected to use the returned value in an async manner instead of using blocking calls like get provided by Future.

Solution 3

One is an interface and the other is a class. Usually you return the interface and not the implementation, but I doubt this is the case here. Returning CompletableFuture makes more sense for me.

Unless you are using some other implementation of that interface of course, like Spring's DelegatingCompletableFuture, but from your examples you are not.

Share:
20,495
Ebraheem Alrabeea
Author by

Ebraheem Alrabeea

I have more than 8 years of experience in web development, coding with many frameworks and languages like: Java, Nodejs, Angular, Spring (Boot, MVC, Data, Security), Play, Elasticsearch, Solr, jHipster, Keycloak, Hibernate, JPA, Docker, HTML, Javascript, and Typescript. Right now am working on an IoT platform project that use all possible protocols (HTTP, MQTT, CoAP, LwM2M, SNMP ...) to communicate with different devices. Our platform is developed based on an open source IoT project that use Java, Spring, Nodejs, Angular, and Docker.

Updated on July 09, 2022

Comments

  • Ebraheem Alrabeea
    Ebraheem Alrabeea almost 2 years

    I have seen an example in each of them, but I need to know exactly what is the difference in deep, Because sometimes I think I can use both of them to get the same result, So I want know so that I can choose the correct one?

    What is the benefit of using each of them?

    Like this example both works:

    public CompletionStage<Result> getNextQueryUUID() {
        return CompletableFuture.supplyAsync(() -> {
            String nextId = dbRequestService.getNextRequestQueryUUID();
            return ok(nextId);
        }, executor);
    }
    
    
    public CompletableFuture<Result> getNextQueryUUID() {
        return CompletableFuture.supplyAsync(() -> {
            String nextId = dbRequestService.getNextRequestQueryUUID();
            return ok(nextId);
        }, executor);
    }
    

    This example run in Play framework.

  • Ebraheem Alrabeea
    Ebraheem Alrabeea over 6 years
    I think for the first time it is like the difference between Thread class and Runnable interface, So that there is more methods to use, but even more that will be benefit when I define a field of type CompletableFuture<T> instead of returning value by a method.
  • Ousmane D.
    Ousmane D. over 6 years
    @EbraheemAlrabee the CompletionStage interface simply contains abstract methods for computations which may or may not be asynchronous. so, of course, the implementing type will almost always have more functionality than it's base type, so as mentioned by Eugene within his post unless you're using some other implementation of that interface then it probably makes sense to use CompletableFuture<T> as the target type for now.However there may be more implementing classes in the future, you never know.
  • RafiAlhamd
    RafiAlhamd about 4 years
    Returning a 'concrete class' should be avoided if there is a way to return the 'the super class/interface', unless the CALLER is looking for a 'subclass/concrete-class'. I agree to the answer by @xiao.
  • acmoune
    acmoune about 4 years
    You are both saying the same thing
  • Hermes
    Hermes over 2 years
    As nicely explained by @Xiao, one should prefer to return CompletionStage rather than CompletableFuture.
  • Hermes
    Hermes over 2 years
    As nicely explained by @Xiao, one should prefer to return CompletionStage rather than CompletableFuture.