gpt4 book ai didi

java - 使用 CompletableFuture 抛出已检查的异常

转载 作者:行者123 更新时间:2023-12-04 13:45:17 24 4
gpt4 key购买 nike

Stackoverflow 包含多个关于混合检查异常与 CompletableFuture 的问题.

这里有一些例子:

  • Checked exception with CompletableFuture
  • Java 8 Supplier Exception handling
  • JDK8 CompletableFuture.supplyAsync how to deal with interruptedException

  • 虽然一些答案暗示使用 CompletableFuture.completeExceptionally()他们的方法导致用户代码难以阅读。

    我将使用这个空间来提供一个替代解决方案,以提高可读性。

    请注意,此问题特定于 CompletableFuture。 这使我们能够提供不扩展到更普遍的 lambda 表达式的解决方案。

    最佳答案

    鉴于 Completions实用程序类(下面提供)用户可以无缝地抛出已检查的异常:

    public CompletionStage<String> readLine()
    {
    return Completions.supplyAsync(() ->
    {
    try (BufferedReader br = new BufferedReader(new FileReader("test.txt")))
    {
    return br.readLine();
    }
    });
    }

    lambda 抛出的任何异常(检查与否)都将被包装在 CompletionException 中。 , 与 CompletableFuture 一致对未经检查的异常的行为。

    对于像 thenApply() 这样的中间步骤,事情变得有点难看。但这不是世界末日:
    public CompletionStage<String> transformLine()
    {
    return readLine().thenApply(line ->
    Completions.wrapExceptions(() ->
    {
    if (line.contains("%"))
    throw new IOException("Lines may not contain '%': " + line);
    return "transformed: " + line;
    }));
    }

    这里有一些方法来自 Completions实用程序类。您可以包装其他 CompletableFuture这种方法。
    /**
    * Helper functions for {@code CompletionStage}.
    *
    * @author Gili Tzabari
    */
    public final class Completions
    {
    /**
    * Returns a {@code CompletionStage} that is completed with the value or exception of the {@code CompletionStage}
    * returned by {@code callable} using the supplied {@code executor}. If {@code callable} throws an exception the
    * returned {@code CompletionStage} is completed with it.
    *
    * @param <T> the type of value returned by {@code callable}
    * @param callable returns a value
    * @param executor the executor that will run {@code callable}
    * @return the value returned by {@code callable}
    */
    public static <T> CompletionStage<T> supplyAsync(Callable<T> callable, Executor executor)
    {
    return CompletableFuture.supplyAsync(() -> wrapExceptions(callable), executor);
    }

    /**
    * Wraps or replaces exceptions thrown by an operation with {@code CompletionException}.
    * <p>
    * If the exception is designed to wrap other exceptions, such as {@code ExecutionException}, its underlying cause is wrapped; otherwise the
    * top-level exception is wrapped.
    *
    * @param <T> the type of value returned by the callable
    * @param callable an operation that returns a value
    * @return the value returned by the callable
    * @throws CompletionException if the callable throws any exceptions
    */
    public static <T> T wrapExceptions(Callable<T> callable)
    {
    try
    {
    return callable.call();
    }
    catch (CompletionException e)
    {
    // Avoid wrapping
    throw e;
    }
    catch (ExecutionException e)
    {
    throw new CompletionException(e.getCause());
    }
    catch (Throwable e)
    {
    throw new CompletionException(e);
    }
    }

    /**
    * Returns a {@code CompletionStage} that is completed with the value or exception of the {@code CompletionStage}
    * returned by {@code callable} using the default executor. If {@code callable} throws an exception the returned
    * {@code CompletionStage} is completed with it.
    *
    * @param <T> the type of value returned by the {@code callable}
    * @param callable returns a value
    * @return the value returned by {@code callable}
    */
    public static <T> CompletionStage<T> supplyAsync(Callable<T> callable)
    {
    return CompletableFuture.supplyAsync(() -> wrapExceptions(callable));
    }

    /**
    * Prevent construction.
    */
    private Completions()
    {}
    }

    关于java - 使用 CompletableFuture 抛出已检查的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49705335/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com