下面是我用来理解java8中completablefuture中的异常处理的示例代码。 如果我们按照文档使用特殊方法, 异常方法甚至捕获运行时异常并继续到管道中的最后一个块。
如果我们不使用特殊方法,那么就会打印出来并退出。
如果我的理解不正确,请纠正我。
问题是让我们说如果我想抛出运行时异常并希望应用程序停止。基本上如果我抛出Runtime异常,它就不应该进入下一个流水线块。我该怎么做任何指针都有帮助。
public static void main(String[] args) {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if(i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).exceptionally(it -> {
System.out.println(it.getMessage());
return "empty";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
}
答案 0 :(得分:2)
试试这个:
public static void main(String[] args) {
try {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if (i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).exceptionally(it -> {
if (it.getMessage().contains("ding")) {
throw (RuntimeException) it;
}
System.out.println(it.getMessage());
return "empty";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
retrieveName.join();
} catch (Exception e) {
System.out.println("main() exception, cause=" + e.getCause());
}
}
这是输出:
运行
main()异常,cause = java.lang.RuntimeException:ding
我对您的代码进行了3次小改动:
public T join()
完成时返回结果值,如果异常完成,会抛出(未经检查)异常。
根据OP反馈进行更新-------&gt;
让我们说如果我想抛出运行时异常并希望应用程序 停。基本上如果我抛出Runtime异常,它就不应该继续 管道中的下一个区块。我该怎么办呢。
只需对代码进行2次更改,即可实现所需目标:
[1]完全删除 exceptionally()回调,以便CompletableFuture(CF)以异常终止。在OP代码的 exceptionally()中,异常被吞下而不是重新抛出,并返回CF,因此仍然执行 thenApply()方法。
[2]在main()的末尾添加对 retrieveName.join()的调用。这是一个阻塞调用,但由于该线程已终止,但异常与示例代码不相关。 join()方法将提取抛出的 RunTimeException 并重新抛出它,包含在 CompletionException 中。
以下是修改过的代码:
public static void main(String[] args) {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if(i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
retrieveName.join();
}
注意: