Devolución de llamada con CompletableFuture

Estoy tratando de crear una callback muy simple usando algunas cadenas. El sentido del código del IDE es que gime sobre una llamada no verificada excepcionalmente. ¿Alguien puede darme una solución para esto? La idea al final es envolver una llamada de red para que se devuelva el resultado prometido y pueda agregar funciones adicionales según sea necesario.

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() { @Override public void accept(String result, String s) { System.out.println(result.toString()); } }) .exceptionally(new Function() { @Override public Exception apply(Exception e) { e.printStackTrace(); return e; } } ).thenApplyAsync(new Function() { @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!"); } } } 

En primer lugar, su clase MakesANetworkCall implementa el tipo de Supplier sin MakesANetworkCall lugar del Supplier . Esto desactivará de manera efectiva la comprobación de tipo y ocultará todos los errores que cometió, por lo que no es la única advertencia que debe preocuparle, ya que no es lo único incorrecto en su código:

  • El BiConsumer pasó a whenComplete debería poder consumir un Throwable como su segundo argumento.

  • La Function pasada a exceptionally debería consumir un Throwable y devolver un resultado alternativo.

Además, está invocando un método static con la expresión new CompletableFuture() como objective y tiene una expresión de creación de cadena obsoleta como new String("Major Tom reporting!") Donde la simple constante "Major Tom reporting!" haré En general, parece que siempre intenta utilizar un método inapropiado, es decir, uno diseñado para consumir cosas que no usa o uno para proporcionar un valor donde no tiene uno. Considera esto:

 CompletableFuture.supplyAsync(new MakesANetworkCall()) .thenAccept(result -> System.out.println(result)) .exceptionally(e -> { e.printStackTrace(); return null;}) .thenRun(()->System.out.println("Last action of all!")); 

Esto hace lo que parece ser tu intención. Si se asegura de que MakesANetworkCall implemente correctamente el Supplier , esto debe comstackrse sin ninguna advertencia.

Su problema principal es con la class MakesANetworkCall implements Supplier { . Esto está utilizando tipos en bruto y, por lo tanto, oculta más problemas. class MakesANetworkCall implements Supplier { eso a la class MakesANetworkCall implements Supplier { y arregla todos los problemas subsiguientes y obtendrá:

  CompletableFuture.supplyAsync(new MakesANetworkCall()) // Not  .whenComplete(new BiConsumer() { @Override public void accept(String result, Throwable t) { System.out.println(result); } }) // Not  .exceptionally(new Function() { @Override public String apply(Throwable t) { t.printStackTrace(); // Must return a Streing return t.getMessage(); } } ).thenApplyAsync(new Function() { @Override public String apply(String o) { System.out.println("Last action of all!"); return null; } }); 

CompletableFuture.exceptionally se declara así:

 public CompletableFuture exceptionally(Function fn); 

Le está pasando una Function , mientras que debería pasarle una Function .