文章目录

  • 简介
  • 处理Unchecked Exception
  • 处理checked Exception
  • 总结

java 8 lambda表达式中的异常处理

简介

java 8中引入了lambda表达式,lambda表达式可以让我们的代码更加简介,业务逻辑更加清晰,但是在lambda表达式中使用的Functional Interface并没有很好的处理异常,因为JDK提供的这些Functional Interface通常都是没有抛出异常的,这意味着需要我们自己手动来处理异常。

因为异常分为Unchecked Exception和checked Exception,我们分别来讨论。

处理Unchecked Exception

Unchecked exception也叫做RuntimeException,出现RuntimeException通常是因为我们的代码有问题。RuntimeException是不需要被捕获的。也就是说如果有RuntimeException,没有捕获也可以通过编译。

我们看一个例子:

List<Integer> integers = Arrays.asList(1,2,3,4,5);integers.forEach(i -> System.out.println(1 / i));

这个例子是可以编译成功的,但是上面有一个问题,如果list中有一个0的话,就会抛出ArithmeticException。

虽然这个是一个Unchecked Exception,但是我们还是想处理一下:

        integers.forEach(i -> {try {System.out.println(1 / i);} catch (ArithmeticException e) {System.err.println("Arithmetic Exception occured : " + e.getMessage());}});

上面的例子我们使用了try,catch来处理异常,简单但是破坏了lambda表达式的最佳实践。代码变得臃肿。

我们将try,catch移到一个wrapper方法中:

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

则原来的调用变成这样:

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

但是上面的wrapper固定了捕获ArithmeticException,我们再将其改编成一个更通用的类:

    static <T, E extends Exception> Consumer<T>consumerWrapperWithExceptionClass(Consumer<T> consumer, Class<E> clazz) {return i -> {try {consumer.accept(i);} catch (Exception ex) {try {E exCast = clazz.cast(ex);System.err.println("Exception occured : " + exCast.getMessage());} catch (ClassCastException ccEx) {throw ex;}}};}

上面的类传入一个class,并将其cast到异常,如果能cast,则处理,否则抛出异常。

这样处理之后,我们这样调用:

integers.forEach(consumerWrapperWithExceptionClass(i -> System.out.println(1 / i),ArithmeticException.class));

处理checked Exception

checked Exception是必须要处理的异常,我们还是看个例子:

    static void throwIOException(Integer integer) throws IOException {}
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);integers.forEach(i -> throwIOException(i));

上面我们定义了一个方法抛出IOException,这是一个checked Exception,需要被处理,所以在下面的forEach中,程序会编译失败,因为没有处理相应的异常。

最简单的办法就是try,catch住,如下所示:

        integers.forEach(i -> {try {throwIOException(i);} catch (IOException e) {throw new RuntimeException(e);}});

当然,这样的做法的坏处我们在上面已经讲过了,同样的,我们可以定义一个新的wrapper方法:

    static <T> Consumer<T> consumerWrapper(ThrowingConsumer<T, Exception> throwingConsumer) {return i -> {try {throwingConsumer.accept(i);} catch (Exception ex) {throw new RuntimeException(ex);}};}

我们这样调用:

integers.forEach(consumerWrapper(i -> throwIOException(i)));

我们也可以封装一下异常:

static <T, E extends Exception> Consumer<T> consumerWrapperWithExceptionClass(ThrowingConsumer<T, E> throwingConsumer, Class<E> exceptionClass) {return i -> {try {throwingConsumer.accept(i);} catch (Exception ex) {try {E exCast = exceptionClass.cast(ex);System.err.println("Exception occured : " + exCast.getMessage());} catch (ClassCastException ccEx) {throw new RuntimeException(ex);}}};}

然后这样调用:

integers.forEach(consumerWrapperWithExceptionClass(i -> throwIOException(i), IOException.class));

总结

本文介绍了如何在lambda表达式中处理checked和unchecked异常,希望能给大家一些帮助。

本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/lambda-exception

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com

java 8 lambda表达式中的异常处理相关推荐

  1. Java高级-Lambda 表达式、异常处理、集合、泛型、List集合、Map集合、Collections类

    目录 Lambda 表达式 Java Lambda 表达式的优缺点 异常处理 Exception 处理及常见异常 try catch语句 try catch finally语句 throws 声明异常 ...

  2. java lambda 表达式中的双冒号和箭头的用法 ::

    先构造一些数据,创建一个User类 java lambda 表达式中的双冒号的用法 :: 双冒号运算就是Java中的[方法引用],[方法引用]的格式是 类名::方法名 如下图所示 User是一个类, ...

  3. java lambda 两个冒号_java lambda 表达式中的双冒号的用法说明 ::

    双冒号运算就是java中的[方法引用],[方法引用]的格式是 类名::方法名 注意是方法名哦,后面没有括号"()"哒.为啥不要括号,因为这样的是式子并不代表一定会调用这个方法.这种 ...

  4. JAVA 8 lambda 表达式实现按某个属性值查找对象集合中符合条件的对象

    转载自:https://www.cnblogs.com/lindsayYang/p/9843599.html JAVA 8 lambda 表达式实现按某个属性值查找对象集合中符合条件的对象 当前的需求 ...

  5. java supplier t_在Java中如何使用lambda表达式中的Supplier T接口?

    Supplier接口是一个预定义的接口,表示结果的提供者.它是使用lambda表达式.方法引用或默认构造函数实例化的.Supplier接口的函数方法是get()方法.此接口属于java.util.fu ...

  6. Java中的匿名函数格式_「创作开运礼」Java之Lambda表达式的省略格式

    各位小伙伴们大家好,在之前的文章中小编介绍了使用Lambda表达式来省略匿名内部类当中,一些不必要的代码,这次小编要介绍的是Lambda表达式的省略格式,这种格式下代码更加简单,具体如下: Lambd ...

  7. 10个Java 8 Lambda表达式经典示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表 达式,它将允许我们将行为传到函数里.在J ...

  8. 深入理解Java 8 Lambda表达式(Oracle官方文档版)

    Java 8 问世三年了,9马上也要问世了,所以,嗯,我要开始学8了-- 官方文档:http://docs.oracle.com/javase/tutorial/java/javaOO/lambdae ...

  9. Java 8 Lambda 表达式详解

    版权声明:本文由吴仙杰创作整理,转载请注明出处:https://segmentfault.com/a/1190000009186509 1. 引言 在 Java 8 以前,若我们想要把某些功能传递给某 ...

最新文章

  1. pxe+kickstart无人值守安装
  2. sh变量特性(3)默认特性
  3. 持续集成部署Jenkins工作笔记0001---持续集成、持续部署、持续交付的概念
  4. Cakephp 创建无模型的Controller
  5. ALV 行、列、单元格颜色设置
  6. JVM基础学习之基本概念、可见性与同步
  7. dll封装成activex控件_Qt编写自定义控件26-平铺背景控件
  8. 医药行业的契约锁电子签章应用场景:印章统一管,核心业务在线签
  9. bex5 php,Bex5开发技巧之如何在列表中显示主键字段
  10. 软考中级软件设计师基础知识总结
  11. should be described in NUMA config 和 CPU feature cmt not found
  12. iText API操作doc文档
  13. C|倒三角(trangle)
  14. python用保留字while实现无限循环_Python中无限循环需要什么条件
  15. python自动产品分类_商品分类(一堆多)
  16. 查看Window系列本地账户密码
  17. Java核心技术卷一基础知识第10版demo实例
  18. wps去掉列的重复记录
  19. 【英语】八月英语总结
  20. 水下无人潜航器集群综述 | 2020年2月「AI产品/工程落地」

热门文章

  1. DVWA设置mysql_解决DVWA配置报错
  2. 视音频编解码学习工程:FLV封装格式分析器
  3. C++虚继承(一) --- vtordisp字段
  4. 局域网arpsniffer源码剖析
  5. lcx源代码以及免杀的研究
  6. 消息中间件选型分析——从Kafka与RabbitMQ的对比来看全局
  7. Spring循环依赖的三种方式,你都清楚吗?
  8. MySQL大表优化技术要点科普
  9. 音视频技术开发周刊 | 170
  10. 观察:谁能拯救视频平台的高昂带宽成本?