我是 CompletableFuture 的新手,我想调用一个可以抛出异常的方法 MetadataLoginUtil::login。但是,尽管我“异常”地编写了下面的代码,但并未编译。它说我必须在 try & catch 中包装 MetadataLoginUtil::login'。

请指教。
先谢谢了!

public void run() throws ConnectionException {
    CompletableFuture<Void> mt = CompletableFuture.supplyAsync(MetadataLoginUtil::login)
            .exceptionally(e -> {
                System.out.println(e);
                return null;
            })
            .thenAccept(e -> System.out.println(e));
}

最佳答案

CompletableFuture.supplyAsync(Supplier<U>) 需要一个 java.util.function.Supplier<U> 实例,而 Supplier.get() 方法的签名不允许检查异常。要清楚地看到这一点,请注意 CompletableFuture.supplyAsync(MetadataLoginUtil::login) 等价于

CompletableFuture<Void> mt = CompletableFuture.supplyAsync(new Supplier<Void>() {
        @Override
        public Void get() {
            return MetadataLoginUtil.login();
        }
    })

这显然无法编译。

您可以处理 Supplier 内部的异常,将 CompletableFuture.supplyAsync(MetadataLoginUtil::login).exceptionally(e -> {System.out.println(e); return null; } ) 更改为
CompletableFuture.supplyAsync(() -> {
        try {
            return MetadataLoginUtil.login();
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
    })

它并不漂亮,但 CompletableFuture 的 API 似乎不能很好地处理已检查的异常。

关于java - 调用 supplyAsync 时尝试并捕获,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40795420/

10-12 03:51