问题很简单:我正在寻找一种优雅的方式,将<code>CompletableFuture#与<code>CompletableFuture#supplySync</code>一起使用。这是不起作用的:
private void doesNotCompile() {
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(() -> throwSomething())
.exceptionally(Throwable::getMessage);
}
private String throwSomething() throws Exception {
throw new Exception();
}
我认为异常()
背后的想法正是为了处理抛出异常
的情况。然而,如果我这样做,它会起作用:
private void compiles() {
CompletableFuture<String> thisIsFine = CompletableFuture.supplyAsync(() -> {
try {
throwSomething();
return "";
} catch (Exception e) {
throw new RuntimeException(e);
}
}).exceptionally(Throwable::getMessage);
}
我可以这样做,但是这看起来很可怕,而且让事情更难维护。有没有一种不需要将所有< code>Exception转换为< code>RuntimeException的方法来保持这种简洁?
这可能不是一个超级受欢迎的库,但我们使用它(有时我也在那里工作;次要的)内部:没有例外。它真的,真的很适合我的口味。这不是它唯一拥有的东西,但肯定涵盖了您的使用案例:
以下是一个示例:
import com.machinezoo.noexception.Exceptions;
import java.util.concurrent.CompletableFuture;
public class SO64937499 {
public static void main(String[] args) {
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(Exceptions.sneak().supplier(SO64937499::throwSomething))
.exceptionally(Throwable::getMessage);
}
private static String throwSomething() throws Exception {
throw new Exception();
}
}
或者,您可以自己创建这些:
final class CheckedSupplier<T> implements Supplier<T> {
private final SupplierThatThrows<T> supplier;
CheckedSupplier(SupplierThatThrows<T> supplier) {
this.supplier = supplier;
}
@Override
public T get() {
try {
return supplier.get();
} catch (Throwable exception) {
throw new RuntimeException(exception);
}
}
}
@FunctionalInterface
interface SupplierThatThrows<T> {
T get() throws Throwable;
}
和用法:
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(new CheckedSupplier<>(SO64937499::throwSomething))
.exceptionally(Throwable::getMessage);