MST

星途 面试题库

面试题:Java CompletableFuture异常处理中handle和exceptionally的区别

请详细阐述CompletableFuture的handle方法和exceptionally方法在异常处理上的区别,包括返回值类型、对结果和异常的处理逻辑等方面,并通过代码示例展示两者的不同用法。
32.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

返回值类型

  • handle方法:返回一个CompletableFuture,其泛型类型与handle方法传入的BiFunction的返回类型一致。这意味着无论原始CompletableFuture是否正常完成或发生异常,handle方法都会返回一个新的CompletableFuture,并根据处理逻辑填充相应的值。
  • exceptionally方法:返回一个CompletableFuture,其泛型类型与原始CompletableFuture的泛型类型相同。当原始CompletableFuture发生异常时,exceptionally方法返回的CompletableFuture会包含异常处理逻辑返回的值;若未发生异常,则返回原始CompletableFuture的正常结果。

对结果和异常的处理逻辑

  • handle方法handle方法接收一个BiFunction,该函数的两个参数分别为原始CompletableFuture的结果(若正常完成)和异常(若发生异常)。无论原始CompletableFuture是正常完成还是发生异常,handle方法都会执行传入的BiFunction。根据BiFunction的逻辑,可以基于结果或异常返回不同的值,从而决定新的CompletableFuture的结果。
  • exceptionally方法exceptionally方法接收一个Function,该函数只接收一个Throwable类型的参数,即原始CompletableFuture发生的异常。只有当原始CompletableFuture发生异常时,exceptionally方法才会执行传入的Function,并返回处理异常后的结果。若原始CompletableFuture正常完成,exceptionally方法不会执行,直接返回原始结果。

代码示例

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExceptionHandling {
    public static void main(String[] args) {
        // handle方法示例
        CompletableFuture.supplyAsync(() -> {
            if (Math.random() < 0.5) {
                throw new RuntimeException("Simulated Exception");
            }
            return "Normal Result";
        })
        .handle((result, ex) -> {
            if (ex != null) {
                System.out.println("handle caught exception: " + ex.getMessage());
                return "Handled Exception";
            } else {
                System.out.println("handle got result: " + result);
                return result;
            }
        })
        .thenAccept(System.out::println);

        // exceptionally方法示例
        CompletableFuture.supplyAsync(() -> {
            if (Math.random() < 0.5) {
                throw new RuntimeException("Simulated Exception");
            }
            return "Normal Result";
        })
        .exceptionally(ex -> {
            System.out.println("exceptionally caught exception: " + ex.getMessage());
            return "Exceptionally Handled Exception";
        })
        .thenAccept(System.out::println);

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,CompletableFuture.supplyAsync模拟了一个异步任务,可能会抛出异常。handle方法始终会执行BiFunction,根据是否有异常返回不同结果。exceptionally方法仅在发生异常时执行Function,返回处理后的结果。正常完成时,直接返回原始结果。