sthbuilder
sthbuilder

Reputation: 573

How can Guava just cast future to listenable future?

Exploring the classes in guava to understand the benefits what guava brings, even though with the introduction of java 8, it does not matter that much now, but I am still wondering about how listenableFuture is introduced.

in AbstractListeningExecutorService, there is code snippet like this:

  @Override
  public ListenableFuture<?> submit(Runnable task) {
    return (ListenableFuture<?>) super.submit(task);
  }

here super indicates the super class of AbstractListeningExecutorService, namely ExecutorService, but how can we just cast a superclass (Future) to a subclass (ListenableFuture) like this ?

Upvotes: 1

Views: 859

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279950

You'll notice the direct superclass of AbstractListeningExecutorService is AbstractExecutorService which

Provides default implementations of ExecutorService execution methods. This class implements the submit, invokeAny and invokeAll methods using a RunnableFuture returned by newTaskFor, which defaults to the FutureTask class provided in this package.

That default is overriden in AbstractListeningExecutorService

Abstract ListeningExecutorService implementation that creates ListenableFuture instances for each Runnable and Callable submitted to it

You can also see that in the source code you linked to

  /** @since 19.0 (present with return type {@code ListenableFutureTask} since 14.0) */
  @Override
  protected final <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
    return TrustedListenableFutureTask.create(runnable, value);
  }

That create returns a TrustedListenableFutureTask value, which is a subtype of ListenableFuture.

Those methods in AbstractListeningExecutorService are redeclared so that their return type can be made more specific, ie. ListenableFuture.

Since super.submit(..) has a return type of Future, the return value must be cast to the appropriate subtype, ie. ListenableFuture in this case. And since all calls return the instance created by newTaskFor, it is known that they will be instances of type ListenableFuture. The cast is therefore safe.

Upvotes: 3

Related Questions