guava/src/com/google/common/util/concurrent/Futures.java
@CanIgnoreReturnValue
  // TODO(cpovirk): Consider calling getDone() in our own code.
  public static <V> V getDone(Future<V> future) throws ExecutionException {
    /*
     * We throw IllegalStateException, since the call could succeed later. Perhaps we "should" throw
     * IllegalArgumentException, since the call could succeed with a different argument. Those
     * exceptions' docs suggest that either is acceptable. Google's Java Practices page recommends
     * IllegalArgumentException here, in part to keep its recommendation simple: Static methods
     * should throw IllegalStateException only when they use static state.
     *
     *
     * Why do we deviate here? The answer: We want for fluentFuture.getDone() to throw the same
     * exception as Futures.getDone(fluentFuture).
     */
    checkState(future.isDone(), "Future was expected to be done: %s", future);
    return getUninterruptibly(future);
  }
@CanIgnoreReturnValue
  // TODO(cpovirk): Consider calling getDone() in our own code.
  public static <V> V getDone(Future<V> future) throws ExecutionException {
    /*
     * We throw IllegalStateException, since the call could succeed later. Perhaps we "should" throw
     * IllegalArgumentException, since the call could succeed with a different argument. Those
     * exceptions' docs suggest that either is acceptable. Google's Java Practices page recommends
     * IllegalArgumentException here, in part to keep its recommendation simple: Static methods
     * should throw IllegalStateException only when they use static state.
     *
     *
     * Why do we deviate here? The answer: We want for fluentFuture.getDone() to throw the same
     * exception as Futures.getDone(fluentFuture).
     */
    checkState(future.isDone(), "Future was expected to be done: %s", future);
    return getUninterruptibly(future);
  }
Returns the result of the input {@code Future}, which must have already completed.

<p>The benefits of this method are twofold. First, the name "getDone" suggests to readers that
the {@code Future} is already done. Second, if buggy code calls {@code getDone} on a {@code
Future} that is still pending, the program will throw instead of block. This can be important
for APIs like {@link #whenAllComplete whenAllComplete(...)}{@code .}{@link
FutureCombiner#call(Callable, Executor) call(...)}, where it is easy to use a new input from
the {@code call} implementation but forget to add it to the arguments of {@code
whenAllComplete}.

<p>If you are looking for a method to determine whether a given {@code Future} is done, use the
instance method {@link Future#isDone()}.

@throws ExecutionException if the {@code Future} failed with an exception
@throws CancellationException if the {@code Future} was cancelled
@throws IllegalStateException if the {@code Future} is not done
@since 20.0