Approach 1, wrap it:
You can write a static function
<T> ListenableFuture<T> unwrapListenableFuture
(ListenableFuture<ListenableFuture<T>> nested)
{
return new Wrapper(nested);
}
where Wrapper could be some nested (even anonymous) class which
implements the interface using the "nested" object (implementations
should be straightforward).
Downsides:
It adds an additional case for approach 2, so if you're forced to
approach 2 for other reasons, you won't want this approach.
It increases overall complexity of the project, and future code changes
may turn this from a mere annoyance into a problem.
Advantage: It is guaranteed to work.
Approach 2, crowbar it:
If there is a known list of classes that implement
ListenableFuture<ListenableFuture<T>>, you may be able to cast to the
implementing class; such a class will typically contain a member of type
ListenableFuture<T> which you can extract.
Downside:
This can fail if module boundaries are enforced.
Not many projects actually do this, but it's going to become more
commonplace over time.
Approach 3, avoid it:
That said, having a ListenableFuture<ListenableFuture<T>> anywhere is a
code smell; if you control the code that constructs such an object, you
should change it to just return a ListenableFuture<T> and avoid having
to write that unwrapListenableFuture function.
Downside:
The change may be impossible, because the code that generates the
ListenableFuture<ListenableFuture<T>> is controlled by somebody else who
will not make the change for you, or if you're the person controlling
that code, due to time constraints or because you can't (easily) change
the API.
Hope this helps.
Regards,
Jo