I'm trying to create a really simple callback using some Strings. The IDE's code sense is is moaning about an unchecked call to exceptionally. Can anyone give me a fix for this? The idea in the end is to wrap a network call so that the promised result is returned and I can tack on additional functions as needed.
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class FuturesTest {
public static void main(String[] args) throws Exception {
new FuturesTest().go();
}
private void go() throws ExecutionException, InterruptedException {
CompletableFuture.supplyAsync(new MakesANetworkCall())
.whenComplete(new BiConsumer<String, String>() {
@Override
public void accept(String result, String s) {
System.out.println(result.toString());
}
})
.exceptionally(new Function<Exception, Exception>() {
@Override
public Exception apply(Exception e) {
e.printStackTrace();
return e;
}
}
).thenApplyAsync(new Function<String, String>() {
@Override
public String apply(String o) {
System.out.println("Last action of all!");
return null;
}
});
System.out.println("Main thread will sleep");
Thread.sleep(2500);
System.out.println("Program over");
}
class MakesANetworkCall implements Supplier {
@Override
public String get() {
try {
System.out.println("Ground control to Major Tom");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// int i = 2/0;
return new String("Major Tom reporting!");
}
}
}
First of all, your class MakesANetworkCall
implements the raw type Supplier
instead of Supplier<String>
. This will effectively disable the type checking and hide all errors you made, so it’s not the single warning you should worry about, as that’s not the only thing wrong in your code:
The BiConsumer
passed to whenComplete
should be able to consume a Throwable
as its second argument.
The Function
passed to exceptionally
should consume a Throwable
and return an alternative result.
Further, you are invoking a static
method using the expression new CompletableFuture<String>()
as its target and you have an obsolete string creation expression as new String("Major Tom reporting!")
where the simple constant "Major Tom reporting!"
will do. Generally, you seem to try to always use an inappropriate method, i.e. one designed to consume things you don’t use or one for supplying a value where you don’t have one. Consider this:
CompletableFuture.supplyAsync(new MakesANetworkCall())
.thenAccept(result -> System.out.println(result))
.exceptionally(e -> { e.printStackTrace(); return null;})
.thenRun(()->System.out.println("Last action of all!"));
This does what seems to be your intention. If you ensure that your MakesANetworkCall
correctly implements Supplier<String>
, this should compile without any warnings.
Your core issue is with class MakesANetworkCall implements Supplier {
. This is using raw types and therefore hides further problems. Fix that to class MakesANetworkCall implements Supplier<String> {
and fix all ensuing issues and you get:
CompletableFuture.supplyAsync(new MakesANetworkCall())
// Not <String, String>
.whenComplete(new BiConsumer<String, Throwable>() {
@Override
public void accept(String result, Throwable t) {
System.out.println(result);
}
})
// Not <Exception,Exception>
.exceptionally(new Function<Throwable, String>() {
@Override
public String apply(Throwable t) {
t.printStackTrace();
// Must return a Streing
return t.getMessage();
}
}
).thenApplyAsync(new Function<String, String>() {
@Override
public String apply(String o) {
System.out.println("Last action of all!");
return null;
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With