3 回答

TA貢獻1818條經驗 獲得超11個贊
實例化和拋出大量異??赡軙兊孟喈敯嘿F,這就是為什么它們應該僅限于特殊情況。相反,您可以使用Optional來控制流:
func = (value) -> Optional.of(value + 5);
func = func.andThen((optionalValue) -> {
? ? // Instead of throwing an exception, return an empty Optional
? ? System.out.println("Log the failure");
? ? return Optional.empty();
});
func = func.andThen((optionalValue) -> {
? ? optionalValue.map((value) -> { // This lambda will only execute if optionalValue is not empty
? ? ? ? System.out.println("Reached last function !");
? ? ? ? return value; // map wraps this in an Optional
? ? });
});
// Finally, unwrap the value. Optional provides a number of ways to do this, depending on how you want to handle failure/empty
func = func.andThen((optional) -> optional.orElse(...));
executeFunction(func);

TA貢獻1877條經驗 獲得超1個贊
您可以為函數/可運行對象編寫一個包裝器,在任務失敗時記錄并退出。就像這樣:
class Runnables
{
public static Runnable trying(Runnable... runnables)
{
return () ->
{
int successes = 0;
try
{
for(Runnable runnable : runnables)
{
runnable.run();
successes++;
}
}
catch(Throwable t)
{
logger.error("Exception thrown from "+successes+"th runnable: ",t);
}
};
}
}
然后:
private static void executeFunction(Runnable... runnables)
{
CompletableFuture.supplyAsync(Runnables.trying(runnables));
}

TA貢獻1891條經驗 獲得超3個贊
您可以通過使用CompletableFuture.thenApply
方法來獲得所需的行為。例如:
public class Answer {
? public static void main(String[] args) {
? ? Function<Integer, Integer> fn0 = v -> v + 5;
? ? Function<Integer, Integer> fn1 = v -> {
? ? ? ? throw new RuntimeException("failed");
? ? };
? ? Function<Integer, Integer> fn2 = v -> {
? ? ? ? System.out.println("Reached last function !");
? ? ? ? return v;
? ? };
? ? CompletableFuture.supplyAsync(() -> fn0.apply(100))
? ? ? ? ? ? .thenApply(fn1)
? ? ? ? ? ? .thenApply(fn2)
? ? ? ? ? ? .exceptionally(throwable -> {
? ? ? ? ? ? ? ? // next line prints the exception thrown by fn1, wrapped in java.util.concurrent.CompletionException
? ? ? ? ? ? ? ? System.out.println("Failed with error: " + throwable);?
? ? ? ? ? ? ? ? return 0; // default value, used when exception is thrown
? ? ? ? ? ? });
? }
}
基本上,CompletableFuture鏈將被“開箱即用”的異常中斷,因此不需要額外的處理。
或者,如果您想要更通用的方法:
public class Answer {
? public static void main(String[] args) {
? ? executeAsync(() -> stepOne(100))
? ? ? ? ? ? .thenApply(Answer::stepTwo)
? ? ? ? ? ? .thenApply(Answer::finalStep)
? ? ? ? ? ? .exceptionally(Answer::handleException);
? }
? private static CompletableFuture<Integer> executeAsync(Supplier<Integer> task) {
? ? return CompletableFuture.supplyAsync(task::get);
? }
? private static Integer stepOne(Integer value) {
? ? return value + 5;
? }
? private static Integer stepTwo(Integer value) {
? ? throw new RuntimeException("failed");
? }
? private static Integer finalStep(Integer value) {
? ? System.out.println("Reached last function !");
? ? return value;
? }
? private static Integer handleException(Throwable throwable) {
? ? // next line prints the exception thrown by any step before, wrapped in java.util.concurrent.CompletionException
? ? System.out.println("Failed with error: " + throwable);
? ? return 0; // default value
? }
筆記:
使用thenApply您可以根據需要鏈接任意數量的函數調用
在最后一個示例中,同一類中的方法可以替換為其他類中的方法(不一定是靜態類)
添加回答
舉報