Java 8 Lambda 异常处理

義往昔 1月前 ⋅ 29 阅读

 

java8 lambda表达式利用函数式编程提供精简的方式表达行为。然而,JDK函数式接口没有很好地处理异常,使得处理异常代码非常臃肿和麻烦。本文探讨在lambda表达式中处理异常的一些方式。

处理非检查异常

首先我们通过示例来说明问题。有List和常量除,比如50和list中每个元素除并打印出结果:

List<Integer> integers = Arrays.asList(3, 9, 7, 6, 10, 20);

integers.forEach(i -> System.out.println(50 / i));

上述代码正常工作,但有问题。如果list有元素值为0,那么会抛出异常ArithmeticException: / by zero。我们利用传统的try-catch块处理该异常,打印异常内容并继续执行一个元素:

List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(i -> {
    try {
        System.out.println(50 / i);
    } catch (ArithmeticException e) {
        System.err.println(
          "Arithmetic Exception occured : " + e.getMessage());
    }
});

利用try-catch块解决了问题,但没有了lambda表达式的精简性,不再是一个小函数了。为了解决这个问题,我们给lambda函数写一个lambda包装器。请看代码:

static Consumer<Integer> lambdaWrapper(Consumer<Integer> consumer) {
    return i -> {
        try {
            consumer.accept(i);
        } catch (ArithmeticException e) {
            System.err.println(
              "Arithmetic Exception occured : " + e.getMessage());
        }
    };
}

List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(lambdaWrapper(i -> System.out.println(50 / i)));

上面代码我们首先定义包装方法负责处理异常,然后将其作为参数传给遍历方法。通过包装方法解决了问题,但你可能争辩这仅仅从一个地方删除try-catch,移动到另一个方法中,实际并没有减少代码。

这时事实,因为包装器仅给特定的类型使用,但我们可以使用泛型提升包装方法的使用范围:

https://blog.csdn.net/neweastsun/article/details/82557509

 

 


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: