I wish to write async/await code which is JS-friendly, however, my class inheritance doesn't seem to work:
import java.util.concurrent.CompletableFuture;
class Main {
public static class Promise<T> extends CompletableFuture<T>{}
public static void main(String[] args) {
System.out.println(System.getProperty("java.version"));
// This works:
CompletableFuture<String> p1 = Promise.supplyAsync(()->{
return "foobar";
});
// This doesn't, but i need this:
Promise<String> p2 = Promise.supplyAsync(()->{
return "foobar";
});
}
}
The tricky part is I need to return as Promise<T>
not CompletableFuture<T>
, making a JS-friendly util.
Error:
ERROR!
/tmp/kpS1aJoUkj/Main.java:13: error: incompatible types: no instance(s) of type variable(s) U exist so that CompletableFuture<U> conforms to Promise<String>
Promise<String> p2 = Promise.supplyAsync(()->{
^
where U is a type-variable:
U extends Object declared in method <U>supplyAsync(Supplier<U>)
1 error
If a cast added to the right side of p2, the error is:
ERROR!
Exception in thread "main" java.lang.ClassCastException: class java.util.concurrent.CompletableFuture cannot be cast to class Main$Promise (java.util.concurrent.CompletableFuture is in module java.base of loader 'bootstrap'; Main$Promise is in unnamed module of loader 'app')
at Main.main(Main.java:13)
Tested on https://www.programiz.com/java-programming/online-compiler/
The error you get is because supplyAsync()
returns a CompletableFuture
and you are trying to assign it to a Promise
. The assignment correctly fails to compile because a CompletableFuture
is not a Promise
.
You can work around this by writing your Promise
class to be constructible from a CompletableFuture
- perhaps by holding the CompletableFuture
in a private field and delegating its methods to it.
Then you can override your Promise.supplyAsync
to return a Promise
which contains the CompletableFuture
returned by its super class.