使用CompletableFuture抛出检查异常

包含多个有关将检查的异常与混合使用的问题CompletableFuture

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

我将使用此空间来提供可提高可读性的替代解决方案。

这使我们能够提供更广泛地不扩展到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()

{}

}

以上是 使用CompletableFuture抛出检查异常 的全部内容, 来源链接: utcz.com/qa/422727.html

回到顶部