4

I'm doing static util method which returns completed future with empty optional:

public class CompletableFutureUtils {

    private static final CompletableFuture<Optional<?>> EMPTY_FUT = completedFuture(Optional.empty());

    private static final Optional<?> EMPTY_OPT = Optional.empty();

    @Nonnull
    @SuppressWarnings("unchecked")
    public static <T> CompletableFuture<Optional<T>> emptyOptionalCompletedFuture() {

        // COMPILE ERROR: incompatible types: CompletableFuture<Optional<?>> cannot be converted to CompletableFuture<Optional<T>>
        // return (CompletableFuture<Optional<T>>)EMPTY_FUT;

        return completedFuture((Optional<T>)EMPTY_OPT); // works, but creates new instance every time
    }
}

For the sake of efficiency i want to return the same constant instance of completed CompletableFuture - EMPTY_FUT, but can't cast it to CompletableFuture<Optional<T>> because of unbounded wildcard.

Of course i want to call this completed future method for any type, pretty much the same as Optional.empty() and CompletableFuture.completedFuture(U)

How to cast generic with unbounded wildcard to specific type? Is it possible at all?

radistao
  • 14,889
  • 11
  • 66
  • 92
  • Due to type erasure `Optional` and `Optional>` are the same at runtime, i.e. just `Optional`. Thus is you cast to the raw type the compiler would warn you but should do it without complaints. – Thomas Feb 23 '18 at 12:07

1 Answers1

5

Cast away the type of the CompleteableFuture first, then cast again to the type you want, like this:

return (CompletableFuture<Optional<T>>) (CompletableFuture<?>) EMPTY_FUT;
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • awesome, thx. Didn't know about this "double casting with up casting" – radistao Feb 23 '18 at 12:32
  • ah, it could be even simplified upping bounds of EMPTY_FUT: `CompletableFuture EMPTY_FUT = completedFuture(Optional.empty());` Then `(CompletableFuture>) ` even not needed any more. Could you adjust/edit you answer with this approach? Thanks – radistao Feb 23 '18 at 12:37
  • 1
    You can, but just watch out, in case you accidentally reuse it as, say, a `CompleteableFuture`. At least if you have it as a `CompleteableFuture>`, you have to explicitly cast it away. – Andy Turner Feb 23 '18 at 12:41
  • i see, just in this certain re-usage doesn't have any sense – radistao Feb 23 '18 at 13:29