使用 CompletableFuture 检查异常 [重复]
Posted
技术标签:
【中文标题】使用 CompletableFuture 检查异常 [重复]【英文标题】:Checked exception with CompletableFuture [duplicate] 【发布时间】:2017-01-13 09:27:07 【问题描述】:使用 Java 8
的强大功能 CompletableFuture,我想使用此新功能的异常来转换我的旧异步代码。但是检查的异常让我很困扰。这是我的代码。
CompletableFuture<Void> asyncTaskCompletableFuture =
CompletableFuture.supplyAsync(t -> processor.process(taskParam));
process
方法的签名:
public void process(Message msg) throws MyException;
如何处理 ComletableFuture 中的检查异常?
【问题讨论】:
见***.com/questions/18198176/… - 可能会作为副本关闭 @mjt 我认为这个问题值得在 CompletableFuture 的上下文中讨论,因为这个 API 对异常有特定的处理。 链接的问题更笼统,因此也涵盖了这个问题。 @Tunaki 可能存在与CompletableFuture
相关的更具体的重复项,例如***.com/a/28961083/525036 和***.com/q/23184964/525036,它们都提到了涉及completeExceptionnally()
的解决方案并避免将异常包装在运行时异常中。
这里有一个解决方案,可以让您在不降低代码可读性的情况下使用检查异常:***.com/a/49705336/14731
【参考方案1】:
这种方式我试过了,不知道是不是解决问题的好办法。
@FunctionalInterface
public interface RiskEngineFuncMessageProcessor<Void> extends Supplier<Void>
@Override
default Void get()
try
return acceptThrows();
catch (final Exception e)
throw new RuntimeException(e);
Void acceptThrows() throws Exception;
使用Supplier的FunctionalInterface,我可以包装异常:
final MyFuncProcessor<Void> func = () ->
processor.process(taskParam);
return null;
;
CompletableFuture<Void> asyncTaskCompletableFuture =
CompletableFuture.supplyAsync(func)
.thenAccept(act ->
finishTask();
)
.exceptionally(exp ->
log.error("Failed to consume task", exp);
failTask( exp.getMessage());
return null;
);
【讨论】:
Void
是 JDK 中的一个类。您不应将其用作接口定义中的类型参数名称。要么删除它(因为它在这里似乎没有用),要么使用其他名称。常用单字母名称,我建议使用T
,因为它是Supplier
接口定义中使用的名称。
看来你也不需要返回任何结果,所以你应该用runAsync()
代替supplyAsync()
,用thenRun()
代替thenAccept()
。
我建议抛出 CompletionException
而不是不特定的 RuntimeException
。我会和CompletableFuture
一起顺利工作。以上是关于使用 CompletableFuture 检查异常 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Java 8 CompletableFuture 异常方法的惊人行为
传递给 CompletableFuture.exceptionalally() 的异常处理程序是不是必须返回有意义的值?