ayu*_*ush 7 java exception java-8 completable-future
考虑以下代码 -
public class TestCompletableFuture {
BiConsumer<Integer, Throwable> biConsumer = (x,y) -> {
System.out.println(x);
System.out.println(y);
};
public static void main(String args[]) {
TestCompletableFuture testF = new TestCompletableFuture();
testF.start();
}
public void start() {
Supplier<Integer> numberSupplier = new Supplier<Integer>() {
@Override
public Integer get() {
return SupplyNumbers.sendNumbers();
}
};
CompletableFuture<Integer> testFuture = CompletableFuture.supplyAsync(numberSupplier).whenComplete(biConsumer);
}
}
class SupplyNumbers {
public static Integer sendNumbers(){
return 25; // just for working sake its not correct.
}
}
Run Code Online (Sandbox Code Playgroud)
以上的事情很好.但是sendNumbers也可以在我的情况下抛出一个检查过的异常,例如:
class SupplyNumbers {
public static Integer sendNumbers() throws Exception {
return 25; // just for working sake its not correct.
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想y在我的处理中处理这个异常biConsumer.这将帮助我在单个函数(biConsumer)中处理结果以及异常(如果有的话).
有任何想法吗?我可以CompletableFuture.exceptionally(fn)在这里或其他什么地方使用?
Hol*_*ger 16
当您想要处理已检查的异常时,使用标准功能接口的工厂方法没有帮助.当您将代码捕获到lambda表达式中时,您遇到的问题是catch子句需要CompletableFuture实例来设置异常,而工厂方法需要Supplier,鸡和蛋.
您可以使用类的实例字段在创建后允许变异,但最终,生成的代码不是干净的,而且比Executor基于直接的解决方案更复杂.该文件CompletableFuture说:
- 所有没有显式Executor参数的异步方法都是使用
ForkJoinPool.commonPool()... 执行的.
所以你知道以下代码将显示CompletableFuture.supplyAsync(Supplier)直接处理检查异常时的标准行为:
CompletableFuture<Integer> f=new CompletableFuture<>();
ForkJoinPool.commonPool().submit(()-> {
try { f.complete(SupplyNumbers.sendNumbers()); }
catch(Exception ex) { f.completeExceptionally(ex); }
});
Run Code Online (Sandbox Code Playgroud)
文件还说:
...为了简化监视,调试和跟踪,所有生成的异步任务都是标记接口的实例
CompletableFuture.AsynchronousCompletionTask.
如果您希望遵循此约定以使解决方案更像原始supplyAsync方法,请将代码更改为:
CompletableFuture<Integer> f=new CompletableFuture<>();
ForkJoinPool.commonPool().submit(
(Runnable&CompletableFuture.AsynchronousCompletionTask)()-> {
try { f.complete(SupplyNumbers.sendNumbers()); }
catch(Exception ex) { f.completeExceptionally(ex); }
});
Run Code Online (Sandbox Code Playgroud)
你已经抓住了这个例外y.也许你没有看到它因为main在CompletableFuture有机会完成之前退出了?
下面的代码按预期打印"null"和"Hello":
public static void main(String args[]) throws InterruptedException {
TestCompletableFuture testF = new TestCompletableFuture();
testF.start();
Thread.sleep(1000); //wait for the CompletableFuture to complete
}
public static class TestCompletableFuture {
BiConsumer<Integer, Throwable> biConsumer = (x, y) -> {
System.out.println(x);
System.out.println(y);
};
public void start() {
CompletableFuture.supplyAsync(SupplyNumbers::sendNumbers)
.whenComplete(biConsumer);
}
}
static class SupplyNumbers {
public static Integer sendNumbers() {
throw new RuntimeException("Hello");
}
}
Run Code Online (Sandbox Code Playgroud)
也许您可以使用 new Object 来包装您的整数和错误,如下所示:
public class Result {
private Integer integer;
private Exception exception;
// getter setter
}
Run Code Online (Sandbox Code Playgroud)
进而:
public void start(){
Supplier<Result> numberSupplier = new Supplier<Result>() {
@Override
public Result get() {
Result r = new Result();
try {
r.setInteger(SupplyNumbers.sendNumbers());
} catch (Exception e){
r.setException(e);
}
return r;
}
};
CompletableFuture<Result> testFuture = CompletableFuture.supplyAsync(numberSupplier).whenComplete(biConsumer);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12550 次 |
| 最近记录: |